[rtems commit] smdk2410: Resurrect missing gp32 files

Joel Sherrill joel at rtems.org
Thu Mar 3 14:12:58 UTC 2016


Module:    rtems
Branch:    master
Commit:    3f5e0961b41873e3c09131ef0b5a72f1c4fe3374
Changeset: http://git.rtems.org/rtems/commit/?id=3f5e0961b41873e3c09131ef0b5a72f1c4fe3374

Author:    Joel Sherrill <joel at rtems.org>
Date:      Tue Mar  1 12:46:18 2016 -0600

smdk2410: Resurrect missing gp32 files

When the gp32 BSP was obsoleted and removed, files were deleted that
were actually used by the gp32.

This was actually a violation of the expected directory structure
and why it wasn't caught. Another example of why continuous integration
testing -- even just building is important.

---

 c/src/lib/libbsp/arm/smdk2410/Makefile.am        |  36 +-
 c/src/lib/libbsp/arm/smdk2410/README             |   9 +-
 c/src/lib/libbsp/arm/smdk2410/console/uart.c     | 245 +++++++++++++
 c/src/lib/libbsp/arm/smdk2410/include/bsp.h      |  73 +++-
 c/src/lib/libbsp/arm/smdk2410/preinstall.am      |   4 +-
 c/src/lib/libbsp/arm/smdk2410/smc/smc.c          | 417 +++++++++++++++++++++++
 c/src/lib/libbsp/arm/smdk2410/smc/smc.h          |  44 +++
 c/src/lib/libbsp/arm/smdk2410/start/start.S      | 198 +++++++++++
 c/src/lib/libbsp/arm/smdk2410/startup/bspidle.c  |  23 ++
 c/src/lib/libbsp/arm/smdk2410/startup/bspreset.c |   5 +-
 c/src/lib/libbsp/arm/smdk2410/startup/bspstart.c |  89 +++++
 c/src/lib/libbsp/arm/smdk2410/startup/memmap.c   |  12 +-
 12 files changed, 1111 insertions(+), 44 deletions(-)

diff --git a/c/src/lib/libbsp/arm/smdk2410/Makefile.am b/c/src/lib/libbsp/arm/smdk2410/Makefile.am
index 7fce249..f2bf22d 100644
--- a/c/src/lib/libbsp/arm/smdk2410/Makefile.am
+++ b/c/src/lib/libbsp/arm/smdk2410/Makefile.am
@@ -6,8 +6,8 @@ include_bspdir = $(includedir)/bsp
 
 dist_project_lib_DATA = bsp_specs
 
-include_HEADERS = ../gp32/include/bsp.h
-include_HEADERS += ../gp32/smc/smc.h
+include_HEADERS = include/bsp.h
+include_HEADERS += smc/smc.h
 include_HEADERS += ../../shared/include/tm27.h
 
 include_bsp_HEADERS =
@@ -18,7 +18,7 @@ DISTCLEANFILES = include/bspopts.h
 nodist_include_HEADERS += ../../shared/include/coverhd.h
 
 noinst_LIBRARIES = libbspstart.a
-libbspstart_a_SOURCES = ../gp32/start/start.S
+libbspstart_a_SOURCES = start/start.S
 project_lib_DATA = start.$(OBJEXT)
 
 dist_project_lib_DATA += startup/linkcmds
@@ -27,19 +27,26 @@ noinst_LIBRARIES += libbsp.a
 libbsp_a_SOURCES =
 
 # startup
-libbsp_a_SOURCES += \
-    ../gp32/startup/bspstart.c ../gp32/startup/bspidle.c ../../shared/bspclean.c \
-    startup/bspreset.c startup/memmap.c \
-    ../../shared/bootcard.c ../../shared/sbrk.c \
-    ../../shared/bsppredriverhook.c ../../shared/bspgetworkarea.c \
-    ../../shared/gnatinstallhandler.c
+libbsp_a_SOURCES += startup/bspstart.c
+libbsp_a_SOURCES += startup/bspidle.c
+libbsp_a_SOURCES += ../../shared/bspclean.c
+libbsp_a_SOURCES += startup/bspreset.c
+libbsp_a_SOURCES += startup/memmap.c
+libbsp_a_SOURCES += ../../shared/bootcard.c
+libbsp_a_SOURCES += ../../shared/sbrk.c
+
+libbsp_a_SOURCES += ../../shared/bsppredriverhook.c
+libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
+libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c
 libbsp_a_SOURCES += ../../shared/cpucounterread.c
 libbsp_a_SOURCES += ../../shared/cpucounterdiff.c
 # console
-libbsp_a_SOURCES += ../gp32/console/uart.c ../../shared/console.c \
-    ../../shared/console_select.c \
-    ../../shared/console_read.c ../../shared/console_write.c \
-    ../../shared/console_control.c
+libbsp_a_SOURCES += console/uart.c
+libbsp_a_SOURCES += ../../shared/console.c
+libbsp_a_SOURCES += ../../shared/console_select.c
+libbsp_a_SOURCES += ../../shared/console_read.c
+libbsp_a_SOURCES += ../../shared/console_write.c
+libbsp_a_SOURCES += ../../shared/console_control.c
 # IRQ
 include_bsp_HEADERS += ../../shared/include/irq-generic.h \
 	../../shared/include/irq-info.h
@@ -52,7 +59,8 @@ libbsp_a_SOURCES += ../../shared/src/irq-shell.c
 # abort
 libbsp_a_SOURCES += ../shared/abort/abort.c
 # smc
-libbsp_a_SOURCES += ../gp32/smc/smc.c ../gp32/smc/smc.h
+libbsp_a_SOURCES += smc/smc.c
+libbsp_a_SOURCES += smc/smc.h
 
 # Cache
 libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c
diff --git a/c/src/lib/libbsp/arm/smdk2410/README b/c/src/lib/libbsp/arm/smdk2410/README
index 72f1a75..6fc143a 100644
--- a/c/src/lib/libbsp/arm/smdk2410/README
+++ b/c/src/lib/libbsp/arm/smdk2410/README
@@ -1,8 +1,9 @@
 SMDK2410 is a standard evaluation board for samsung s3c2410 ARM9 CPU
 
-This BSP was first developed by xiajiashan <ximenchuixue4016 at sina.com>, based on gp32 Apr/2007
-ZhiMing, Zhang <paopaoerzhang at gmail.com> fix timer defect and run it on skeyey
-Ray, Xu merge this bsp with gp32 on Apr/2008
+This BSP was first developed by xiajiashan <ximenchuixue4016 at sina.com>,
+based on gp32 Apr/2007.
+ZhiMing, Zhang <paopaoerzhang at gmail.com> fix timer defect and run
+it on skeye. Ray, Xu merged this bsp with gp32 on Apr/2008
 
-pls refer to wiki on how to run this BSP on skyeye.
+This BSP can be run on the Skyeye simulator.
 
diff --git a/c/src/lib/libbsp/arm/smdk2410/console/uart.c b/c/src/lib/libbsp/arm/smdk2410/console/uart.c
new file mode 100644
index 0000000..9878c33
--- /dev/null
+++ b/c/src/lib/libbsp/arm/smdk2410/console/uart.c
@@ -0,0 +1,245 @@
+/*
+ *  console driver for S3C2400 UARTs
+ *
+ *  This driver uses the shared console driver in
+ *  ...../libbsp/shared/console.c
+ *
+ *  If you want the driver to be interrupt driven, you
+ *  need to write the ISR, and in the ISR insert the
+ *  chars into termios's queue.
+ *
+ *  Copyright (c) 2004 Cogent Computer Systems
+ *  Written by Jay Monkman <jtm at lopingdog.com>
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+*/
+#include <bsp.h>                /* Must be before libio.h */
+#include <rtems/libio.h>
+#include <termios.h>
+#include <rtems/bspIo.h>
+
+/* Put the CPU (or UART) specific header file #include here */
+#include <s3c24xx.h>
+#include <libchip/serial.h>
+#include <libchip/sersupp.h>
+
+/* How many serial ports? */
+#define NUM_DEVS       1
+
+int     uart_poll_read(int minor);
+
+int dbg_dly;
+
+/* static function prototypes */
+static int     uart_first_open(int major, int minor, void *arg);
+static int     uart_last_close(int major, int minor, void *arg);
+static int     uart_read(int minor);
+static ssize_t uart_write(int minor, const char *buf, size_t len);
+static void    uart_init(int minor);
+static void    uart_write_polled(int minor, char c);
+static int     uart_set_attributes(int minor, const struct termios *t);
+
+/* These are used by code in console.c */
+unsigned long Console_Configuration_Count = NUM_DEVS;
+
+/* Pointers to functions for handling the UART. */
+const console_fns uart_fns =
+{
+    libchip_serial_default_probe,
+    uart_first_open,
+    uart_last_close,
+    uart_read,
+    uart_write,
+    uart_init,
+    uart_write_polled,   /* not used in this driver */
+    uart_set_attributes,
+    FALSE      /* TRUE if interrupt driven, FALSE if not. */
+};
+
+/*
+ * There's one item in array for each UART.
+ *
+ * Some of these fields are marked "NOT USED". They are not used
+ * by console.c, but may be used by drivers in libchip
+ *
+ */
+console_tbl Console_Configuration_Ports[] = {
+    {
+        "/dev/com0",                      /* sDeviceName */
+        SERIAL_CUSTOM,                    /* deviceType */
+        &uart_fns,                        /* pDeviceFns */
+        NULL,                             /* deviceProbe */
+        NULL,                             /* pDeviceFlow */
+        0,                                /* ulMargin - NOT USED */
+        0,                                /* ulHysteresis - NOT USED */
+        NULL,                             /* pDeviceParams */
+        0,                                /* ulCtrlPort1  - NOT USED */
+        0,                                /* ulCtrlPort2  - NOT USED */
+        0,                                /* ulDataPort  - NOT USED */
+        NULL,                             /* getRegister - NOT USED */
+        NULL,                             /* setRegister - NOT USED */
+        NULL,                             /* getData - NOT USED */
+        NULL,                             /* setData - NOT USED */
+        0,                                /* ulClock - NOT USED */
+        0                                 /* ulIntVector - NOT USED */
+    }
+};
+
+/*********************************************************************/
+/* Functions called via termios callbacks (i.e. the ones in uart_fns */
+/*********************************************************************/
+
+/*
+ * This is called the first time each device is opened. If the driver
+ * is interrupt driven, you should enable interrupts here. Otherwise,
+ * it's probably safe to do nothing.
+ *
+ * Since micromonitor already set up the UART, we do nothing.
+ */
+static int uart_first_open(int major, int minor, void *arg)
+{
+    return 0;
+}
+
+
+/*
+ * This is called the last time each device is closed. If the driver
+ * is interrupt driven, you should disable interrupts here. Otherwise,
+ * it's probably safe to do nothing.
+ */
+static int uart_last_close(int major, int minor, void *arg)
+{
+    return 0;
+}
+
+
+/*
+ * Read one character from UART.
+ *
+ * Return -1 if there's no data, otherwise return
+ * the character in lowest 8 bits of returned int.
+ */
+static int uart_read(int minor)
+{
+    char c;
+
+    if (minor == 0) {
+        if (rUTRSTAT0 & 0x1) {
+            c = rURXH0 & 0xff;
+            return c;
+        } else {
+            return -1;
+        }
+    } else {
+        printk("Unknown console minor number: %d\n", minor);
+        return -1;
+    }
+
+}
+
+
+/*
+ * Write buffer to UART
+ *
+ * return 1 on success, -1 on error
+ */
+static ssize_t uart_write(int minor, const char *buf, size_t len)
+{
+    int i;
+
+    if (minor == 0) {
+        for (i = 0; i < len; i++) {
+            /* Wait for fifo to have room */
+            while(!(rUTRSTAT0 & 0x2)) {
+                continue;
+            }
+
+           rUTXH0 = (char) buf[i];
+        }
+    } else {
+        printk("Unknown console minor number: %d\n", minor);
+        return -1;
+    }
+
+    return 1;
+}
+
+
+/* Set up the UART. */
+static void uart_init(int minor)
+{
+	int i;
+	unsigned int reg = 0;
+
+	/* enable UART0 */
+	rCLKCON|=0x100;
+
+	/* value is calculated so : (int)(PCLK/16./baudrate) -1 */
+	reg = get_PCLK() / (16 * 115200) - 1;
+
+	/* FIFO enable, Tx/Rx FIFO clear */
+	rUFCON0 = 0x07;
+	rUMCON0 = 0x0;
+	/* Normal,No parity,1 stop,8 bit */
+	rULCON0 = 0x3;
+	/*
+	 * tx=level,rx=edge,disable timeout int.,enable rx error int.,
+	 * normal,interrupt or polling
+	 */
+	rUCON0 = 0x245;
+	rUBRDIV0 = reg;
+
+	for (i = 0; i < 100; i++);
+
+}
+
+/* I'm not sure this is needed for the shared console driver. */
+static void    uart_write_polled(int minor, char c)
+{
+    uart_write(minor, &c, 1);
+}
+
+/* This is for setting baud rate, bits, etc. */
+static int     uart_set_attributes(int minor, const struct termios *t)
+{
+    return 0;
+}
+
+/***********************************************************************/
+/*
+ * The following functions are not used by TERMIOS, but other RTEMS
+ * functions use them instead.
+ */
+/***********************************************************************/
+/*
+ * Read from UART. This is used in the exit code, and can't
+ * rely on interrupts.
+*/
+int uart_poll_read(int minor)
+{
+    return uart_read(minor);
+}
+
+
+/*
+ * Write a character to the console. This is used by printk() and
+ * maybe other low level functions. It should not use interrupts or any
+ * RTEMS system calls. It needs to be very simple
+ */
+static void _BSP_put_char( char c ) {
+    uart_write_polled(0, c);
+    if (c == '\n') {
+        uart_write_polled(0, '\r');
+    }
+}
+
+BSP_output_char_function_type BSP_output_char = _BSP_put_char;
+
+static int _BSP_get_char(void)
+{
+  return uart_poll_read(0);
+}
+
+BSP_polling_getchar_function_type BSP_poll_char = _BSP_get_char;
diff --git a/c/src/lib/libbsp/arm/smdk2410/include/bsp.h b/c/src/lib/libbsp/arm/smdk2410/include/bsp.h
index d85e7b8..6b6ea02 100644
--- a/c/src/lib/libbsp/arm/smdk2410/include/bsp.h
+++ b/c/src/lib/libbsp/arm/smdk2410/include/bsp.h
@@ -1,19 +1,17 @@
 /**
  * @file
  * @ingroup arm_smdk2410
- * @brief Global BSP definitions.
+ * @brief Global BSP definitons.
  */
 
-/*-------------------------------------------------------------------------+
-| bsp.h - ARM BSP
-|
-| Copyright (c) Ray,Xu  mailto:ray.cn AT gmail dot com
-|
-|  The license and distribution terms for this file may be
-|  found in the file LICENSE in this distribution or at
-|  http://www.rtems.org/license/LICENSE.
-+--------------------------------------------------------------------------*/
-
+/*
+ *  Copyright (c) Canon Research France SA.]
+ *  Emmanuel Raguet, mailto:raguet at crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
 
 #ifndef LIBBSP_ARM_SMDK2410_BSP_H
 #define LIBBSP_ARM_SMDK2410_BSP_H
@@ -21,22 +19,61 @@
 #include <bspopts.h>
 #include <bsp/default-initial-extension.h>
 
+#include <rtems.h>
+#include <rtems/iosupp.h>
+#include <rtems/console.h>
+#include <rtems/clockdrv.h>
+#include <s3c24xx.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define BSP_FEATURE_IRQ_EXTENSION
+
 /**
- * @defgroup arm_smdk2410 SMDK2410 Support
- * @ingroup bsp_arm
- * @brief SMDK2410 Support Package
+ * @brief functions to get the differents s3c2400 clks
+ * @{
  */
 
+uint32_t get_FCLK(void);
+uint32_t get_HCLK(void);
+uint32_t get_PCLK(void);
+uint32_t get_UCLK(void);
+
+/** @} */
+
+/* What is the input clock freq in hertz? */
+/** @brief 12 MHz oscillator */
+#define BSP_OSC_FREQ  12000000
+/** @brief FCLK=133Mhz */
+#define M_MDIV 81
+#define M_PDIV 2
+#define M_SDIV 1
+/** @brief HCLK=FCLK/2, PCLK=FCLK/2 */
+#define M_CLKDIVN 2
+/** @brief enable refresh */
+#define REFEN	0x1
+/** @brief CBR(CAS before RAS)/auto refresh */
+#define TREFMD	0x0
+/** @brief 2 clk */
+#define Trp	0x0
+/** @brief 7 clk */
+#define Trc	0x3
+/** @brief 3 clk */
+#define Tchr	0x2
+
 /**
- *  This file will not be pre-installed because the smdk2410 BSP uses
- *  the bsp.h in gp32 currently.  This file is a placeholder. If you
- *  need to add something specical for your 2410 BSP please override
- *  this file with your own and change Makefile.am
+ * @brief This BSP provides its own IDLE thread to override the RTEMS one.
+ *
+ *  So we prototype it and define the constant confdefs.h expects
+ *  to configure a BSP specific one.
  */
+void *bsp_idle_thread(uintptr_t ignored);
+
+/** @} */
+
+#define BSP_IDLE_TASK_BODY bsp_idle_thread
 
 #ifdef __cplusplus
 }
diff --git a/c/src/lib/libbsp/arm/smdk2410/preinstall.am b/c/src/lib/libbsp/arm/smdk2410/preinstall.am
index 01d4e66..1d72ddf 100644
--- a/c/src/lib/libbsp/arm/smdk2410/preinstall.am
+++ b/c/src/lib/libbsp/arm/smdk2410/preinstall.am
@@ -37,11 +37,11 @@ $(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_LIB)/bsp_specs
 PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs
 
-$(PROJECT_INCLUDE)/bsp.h: ../gp32/include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
+$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h
 
-$(PROJECT_INCLUDE)/smc.h: ../gp32/smc/smc.h $(PROJECT_INCLUDE)/$(dirstamp)
+$(PROJECT_INCLUDE)/smc.h: smc/smc.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/smc.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/smc.h
 
diff --git a/c/src/lib/libbsp/arm/smdk2410/smc/smc.c b/c/src/lib/libbsp/arm/smdk2410/smc/smc.c
new file mode 100644
index 0000000..3b8d5e2
--- /dev/null
+++ b/c/src/lib/libbsp/arm/smdk2410/smc/smc.c
@@ -0,0 +1,417 @@
+/*
+ * s3c2400 smc disk block device implementation
+ *
+ * Squidge's SMC Low-level access routines.
+ * Inspired and derived from routines provided by Samsung Electronics
+ *  M/M R&D Center & FireFly.
+ */
+
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "rtems/blkdev.h"
+#include "rtems/diskdevs.h"
+#include "smc.h"
+#include <rtems/bspIo.h>
+#include <s3c24xx.h>
+
+#define SMC_DEVICE_NAME "/dev/smc"
+#define SMC_SAMSUNG_ID    0xEC
+#define SMC_TOSHIBA_ID    0x98
+
+#define SMC_16MB  0x73
+#define SMC_32MB  0x75
+#define SMC_64MB  0x76
+#define SMC_128MB  0x79
+
+#define LBA_UNUSED      0x80000000
+#define LBA_RESERVED    0x80000001
+
+#define BLOCK_UNUSED    0x80000000
+#define BLOCK_RESERVED  0x80000001
+
+/* SmartMedia Command */
+#define SEQ_DATA_INPUT_CMD   0x80
+#define READ1_CMD            0x00
+#define READ1_1_CMD          0x01
+#define READ2_CMD            0x50
+#define READ_ID_CMD          0x90
+#define RESET_CMD            0xFF
+#define PAGE_PROGRAM_CMD     0x10
+#define BLOCK_ERASE_CMD      0x60
+#define BLOCK_ERASE_CFM_CMD  0xD0
+#define READ_STATUS_CMD      0x70
+#define RESET_PTR_CMD        0x00
+
+
+/* Internal SMC disk descriptor */
+struct SMC_INFO {
+  uint8_t  id[3];
+  uint32_t bytes_per_page;
+  uint32_t pages_per_block;
+  uint32_t blocks;
+  uint32_t mb;
+};
+
+/* Ths S3c2410 uses a different register map */
+#ifdef CPU_S3C2410
+#define rPBDAT rGPBDAT
+#define rPBCON rGPBCON
+#define rPDDAT rGPDDAT
+#define rPEDAT rGPEDAT
+#endif
+
+
+static struct SMC_INFO smc_info;
+
+uint32_t smc_l2p[0x2000];
+uint32_t smc_p2l[0x2000];
+
+#define sm_busy() while (!(rPDDAT & 0x200))
+#define sm_chip_en() rPDDAT &= (~0x80)
+#define sm_chip_dis() rPDDAT |= 0x80
+#define sm_cle_en() rPEDAT |= 0x20
+#define sm_cle_dis() rPEDAT &= (~0x20)
+#define sm_ale_en() rPEDAT |= 0x10
+#define sm_ale_dis() rPEDAT &= (~0x10)
+#define sm_wp_en() rPDDAT &= (~0x40)
+#define sm_wp_dis() rPDDAT |= 0x40
+#define sm_read_en() rPBCON &= 0xFFFF0000
+#define sm_read_dis() rPBCON = (rPBCON & 0xFFFF0000) | 0x5555
+#define sm_write_en() sm_read_dis()
+#define sm_write_dis() sm_read_en()
+
+static void sm_write( uint8_t data)
+{
+  rPBDAT = (rPBDAT & 0xFF00) | data;
+  rPEDAT &= (~0x08);
+  rPEDAT |= 0x08;
+}
+
+static uint8_t sm_read(void)
+{
+  uint8_t data;
+
+  rPDDAT &= (~0x100);
+  data = rPBDAT & 0xFF;
+  rPDDAT |= 0x100;
+  return data;
+}
+
+static void smc_read_id( uint8_t* buf, uint32_t length)
+{
+  uint32_t i;
+
+  sm_chip_en();
+
+  sm_cle_en();
+  sm_write_en();
+  sm_write(READ_ID_CMD);
+  sm_write_dis();
+  sm_cle_dis();
+
+  sm_ale_en();
+  sm_write_en();
+  sm_write( 0);
+  sm_write_dis();
+  sm_ale_dis();
+
+  sm_read_en();
+  for (i=0;i<length;i++) *(buf+i) = sm_read();
+  sm_read_dis();
+
+  sm_chip_dis();
+}
+
+/* read an entire logical page of 512 bytes.*/
+static uint8_t smc_read_page (uint32_t lpage, uint8_t* buf)
+{
+  uint32_t block, page, i;
+
+  /* convert logical block to physical block
+     and then convert into page suitable for read1 command...
+  */
+  block = lpage >> 5;
+  if (smc_l2p[block] < LBA_UNUSED) {
+    page = smc_l2p[block] << 5;
+    page += (lpage & 0x1F);
+  }
+  else
+    return 0;
+
+  sm_chip_en();
+
+  sm_cle_en();
+  sm_write_en();
+  sm_write(READ1_CMD);
+  sm_write_dis();
+  sm_cle_dis();
+
+  sm_ale_en();
+  sm_write_en();
+  sm_write( 0x00);
+  sm_write( (uint8_t)(page >> 0));
+  sm_write( (uint8_t)(page >> 8));
+  if (smc_info.mb >= 64)
+    sm_write( (uint8_t)(page >> 16));
+  sm_write_dis();
+  sm_ale_dis();
+
+  sm_busy();
+
+  sm_read_en();
+  for (i = 0; i < 512; i++) {
+    *buf = sm_read();
+    buf++;
+  }
+  sm_read_dis();
+  sm_chip_dis();
+
+  sm_busy();
+  return 1;
+}
+
+static void smc_read_spare( uint32_t page, uint8_t* buf, uint8_t length)
+{
+  uint32_t i;
+
+  sm_chip_en();
+
+  sm_cle_en();
+  sm_read_dis();
+  sm_write(READ2_CMD);
+  sm_read_en();
+  sm_cle_dis();
+
+  sm_ale_en();
+  sm_read_dis();
+  sm_write( 0x00);
+  sm_write( (uint8_t)(page >> 0));
+  sm_write( (uint8_t)(page >> 8));
+  if (smc_info.mb >= 64)
+    sm_write( (uint8_t)(page >> 16));
+  sm_read_en();
+  sm_ale_dis();
+
+  sm_busy();
+
+  sm_read_en();
+  for (i=0;i<length;i++)
+    *(buf+i) = sm_read();
+  sm_read_dis();
+
+  sm_chip_dis();
+
+}
+
+static void smc_make_l2p(void)
+{
+  uint32_t pblock, i, j, lblock, zone, count, cnt1, cnt2, cnt3;
+  uint8_t data[512];
+
+  cnt1 = 0;
+  cnt2 = 0;
+  cnt3 = 0;
+
+  for (i=0;i<0x2000;i++) {
+    smc_l2p[i] = LBA_RESERVED;
+    smc_p2l[i] = BLOCK_RESERVED;
+  }
+
+  for (pblock=0;pblock<smc_info.blocks;pblock++) {
+    /* read physical block - first page */
+    smc_read_spare( pblock*smc_info.pages_per_block, (uint8_t*)&data, 16);
+
+    zone = pblock >> 10; /* divide by 1024 to get zone */
+    if ((data[5] == 0xFF) && ((data[6]&0xF8) == 0x10)) {
+      lblock = ((((data[6]<<8)|(data[7]<<0)) >> 1) & 0x03FF) + (zone * 1000);
+      smc_l2p[lblock] = pblock;
+      smc_p2l[pblock] = lblock;
+      cnt1++;
+    } else {
+      count = 0;
+      for (j=0;j<16;j++) {
+        if (data[j] == 0xFF) count++;
+      }
+      if (count == 16) {
+        smc_p2l[pblock] = BLOCK_UNUSED;
+        cnt2++;
+      } else {
+        smc_p2l[pblock] = BLOCK_RESERVED;
+        cnt3++;
+      }
+    }
+  }
+}
+
+
+static void smc_detect( uint8_t id1, uint8_t id2, uint8_t id3)
+{
+  smc_info.id[0] = id1;
+  smc_info.id[1] = id2;
+  smc_info.id[2] = id3;
+  smc_info.mb    = 0;
+  smc_info.bytes_per_page  = 0;
+  smc_info.pages_per_block = 0;
+  smc_info.blocks          = 0;
+
+  switch (id1) {
+    case SMC_SAMSUNG_ID:
+    case SMC_TOSHIBA_ID: {
+      switch (id2) {
+        case SMC_16MB  : smc_info.mb = 16; break;
+        case SMC_32MB  : smc_info.mb = 32; break;
+        case SMC_64MB  : smc_info.mb = 64; break;
+        case SMC_128MB : smc_info.mb = 128; break;
+      }
+      break;
+    }
+  }
+
+  switch (smc_info.mb) {
+    case 16  : smc_info.bytes_per_page = 512; smc_info.pages_per_block = 32; smc_info.blocks = 0x0400; break;
+    case 32  : smc_info.bytes_per_page = 512; smc_info.pages_per_block = 32; smc_info.blocks = 0x0800; break;
+    case 64  : smc_info.bytes_per_page = 512; smc_info.pages_per_block = 32; smc_info.blocks = 0x1000; break;
+    case 128 : smc_info.bytes_per_page = 512; smc_info.pages_per_block = 32; smc_info.blocks = 0x2000; break;
+  }
+}
+
+static void smc_init( void)
+{
+  unsigned char buf[32];
+  int i;
+
+  /* reset smc */
+  sm_chip_en();
+  sm_cle_en();
+  sm_write_en();
+  sm_write(0xFF);
+  sm_write_dis();
+  sm_cle_dis();
+  for(i=0;i<10;i++);
+  sm_busy();
+  sm_chip_dis();
+
+  smc_read_id (buf, 4);
+  smc_detect (buf[0], buf[1], buf[2]);
+  printk ("SMC: [%02X-%02X-%02X-%02X]\n", buf[0], buf[1], buf[2], buf[3]);
+  printk ("SMC size: %dMB detected\n",smc_info.mb);
+  smc_make_l2p();
+}
+
+/* smc_write --
+ * write stub
+ */
+static int smc_write(rtems_blkdev_request *req)
+{
+  rtems_blkdev_request_done(req, RTEMS_SUCCESSFUL);
+  return 0;
+}
+
+
+/* smc_read --
+ * PARAMETERS:
+ *     req - pointer to the READ block device request info
+ *
+ * RETURNS:
+ *     ioctl return value
+ */
+static int
+smc_read(rtems_blkdev_request *req)
+{
+    uint32_t   i;
+    rtems_blkdev_sg_buffer *sg;
+    uint32_t   remains;
+
+    remains = smc_info.bytes_per_page * req->bufnum;
+    sg = req->bufs;
+    for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++)
+    {
+        int count = sg->length;
+        if (count > remains)
+            count = remains;
+        smc_read_page(sg->block,sg->buffer);
+        remains -= count;
+    }
+    rtems_blkdev_request_done(req, RTEMS_SUCCESSFUL);
+    return 0;
+}
+
+/* smc_ioctl --
+ *     IOCTL handler for SMC device.
+ *
+ * PARAMETERS:
+ *      dev  - device number (major, minor number)
+ *      req  - IOCTL request code
+ *      argp - IOCTL argument
+ *
+ * RETURNS:
+ *     IOCTL return value
+ */
+static int
+smc_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
+{
+    switch (req)
+    {
+        case RTEMS_BLKIO_REQUEST:
+        {
+            rtems_blkdev_request *r = argp;
+            switch (r->req)
+            {
+                case RTEMS_BLKDEV_REQ_READ:
+                    return smc_read(r);
+                case RTEMS_BLKDEV_REQ_WRITE:
+                    return smc_write(r);
+                default:
+                    errno = EINVAL;
+                    return -1;
+            }
+            break;
+        }
+
+        default:
+            errno = EINVAL;
+            return -1;
+    }
+}
+
+/* smc_initialize --
+ *     RAM disk device driver initialization. Run through RAM disk
+ *     configuration information and configure appropriate RAM disks.
+ *
+ * PARAMETERS:
+ *     major - RAM disk major device number
+ *     minor - minor device number, not applicable
+ *     arg   - initialization argument, not applicable
+ *
+ * RETURNS:
+ *     none
+ */
+rtems_device_driver
+smc_initialize(
+    rtems_device_major_number major,
+    rtems_device_minor_number minor,
+    void *arg)
+{
+    rtems_status_code rc;
+    dev_t dev;
+    uint32_t block_num;
+
+    rc = rtems_disk_io_initialize();
+    if (rc != RTEMS_SUCCESSFUL)
+        return rc;
+
+    smc_init();
+    block_num = smc_info.blocks << 5;
+
+    dev = rtems_filesystem_make_dev_t(major, 0);
+    rc = rtems_disk_create_phys(dev, 512, block_num,
+                                    smc_ioctl, NULL, SMC_DEVICE_NAME);
+
+    return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/arm/smdk2410/smc/smc.h b/c/src/lib/libbsp/arm/smdk2410/smc/smc.h
new file mode 100644
index 0000000..10ec14a
--- /dev/null
+++ b/c/src/lib/libbsp/arm/smdk2410/smc/smc.h
@@ -0,0 +1,44 @@
+/**
+ * @file
+ * @ingroup smdk2410_smc
+ * @brief SMC disk driver initialization entry point
+ */
+
+#ifndef __SMC_H__
+#define __SMC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtems.h>
+
+#include "rtems/blkdev.h"
+
+/**
+ * @defgroup smdk2410_smc SMC Disk Driver
+ * @ingroup arm_smdk2410
+ * @brief SMC Disk Driver Support
+ * @{
+ */
+
+/**
+ * @brief smc_initialize
+ *     SMC disk driver initialization entry point.
+ */
+rtems_device_driver
+smc_initialize(
+    rtems_device_major_number major,
+    rtems_device_minor_number minor,
+    void *arg);
+
+#define SMC_DRIVER_TABLE_ENTRY \
+    { smc_initialize, GENERIC_BLOCK_DEVICE_DRIVER_ENTRIES }
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/c/src/lib/libbsp/arm/smdk2410/start/start.S b/c/src/lib/libbsp/arm/smdk2410/start/start.S
new file mode 100644
index 0000000..f5f8891
--- /dev/null
+++ b/c/src/lib/libbsp/arm/smdk2410/start/start.S
@@ -0,0 +1,198 @@
+/*
+ * SMDK2410 startup code
+ */
+
+/*
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp/linker-symbols.h>
+
+/* Some standard definitions...*/
+.equ PSR_MODE_USR,       0x10
+.equ PSR_MODE_FIQ,       0x11
+.equ PSR_MODE_IRQ,       0x12
+.equ PSR_MODE_SVC,       0x13
+.equ PSR_MODE_ABT,       0x17
+.equ PSR_MODE_UNDEF,     0x1B
+.equ PSR_MODE_SYS,       0x1F
+
+.equ PSR_I,              0x80
+.equ PSR_F,              0x40
+.equ PSR_T,              0x20
+
+.text
+.globl  _start
+_start:
+	b		_start2
+
+ at ---------------------------------------------------------------------------------
+@ AXF addresses
+ at ---------------------------------------------------------------------------------
+	.word   bsp_section_text_begin
+	.word   bsp_section_rodata_end
+	.word   bsp_section_data_begin
+	.word   bsp_section_bss_end
+	.word   bsp_section_bss_begin
+	.word   bsp_section_bss_end
+
+ at ---------------------------------------------------------------------------------
+@ GamePark magic sequence
+ at ---------------------------------------------------------------------------------
+	.word   0x44450011
+	.word   0x44450011
+	.word   0x01234567
+	.word   0x12345678
+	.word   0x23456789
+	.word   0x34567890
+	.word   0x45678901
+	.word   0x56789012
+	.word   0x23456789
+	.word   0x34567890
+	.word   0x45678901
+	.word   0x56789012
+	.word   0x23456789
+	.word   0x34567890
+	.word   0x45678901
+	.word   0x56789012
+
+ at ---------------------------------------------------------------------------------
+_start2:
+ at ---------------------------------------------------------------------------------
+
+        /*
+         * Since I don't plan to return to the bootloader,
+         * I don't have to save the registers.
+         *
+         * I'll just set the CPSR for SVC mode, interrupts
+         * off, and ARM instructions.
+         */
+        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)
+        msr     cpsr, r0
+
+        /* --- Initialize stack pointer registers */
+        /* Enter IRQ mode and set up the IRQ stack pointer */
+        mov     r0, #(PSR_MODE_IRQ | PSR_I | PSR_F)     /* No interrupts */
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_irq_size
+        ldr     sp, =bsp_stack_irq_begin
+        add     sp, sp, r1
+
+        /* Enter FIQ mode and set up the FIQ stack pointer */
+        mov     r0, #(PSR_MODE_FIQ | PSR_I | PSR_F)     /* No interrupts */
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_fiq_size
+        ldr     sp, =bsp_stack_fiq_begin
+        add     sp, sp, r1
+
+        /* Enter ABT mode and set up the ABT stack pointer */
+        mov     r0, #(PSR_MODE_ABT | PSR_I | PSR_F)     /* No interrupts */
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_abt_size
+        ldr     sp, =bsp_stack_abt_begin
+        add     sp, sp, r1
+
+        /* Set up the SVC stack pointer last and stay in SVC mode */
+        mov     r0, #(PSR_MODE_SVC | PSR_I | PSR_F)     /* No interrupts */
+        msr     cpsr, r0
+        ldr     r1, =bsp_stack_svc_size
+        ldr     sp, =bsp_stack_svc_begin
+        add     sp, sp, r1
+        sub     sp, sp, #0x64
+
+
+	/* disable mmu, I and D caches*/
+	nop
+	nop
+	mrc p15, 0, r0, c1, c0, 0
+	bic r0, r0, #0x01
+	bic r0, r0, #0x04
+	bic r0, r0, #0x01000
+	mcr p15, 0, r0, c1, c0, 0
+	nop
+	nop
+
+	/* clean data cache */
+	mov   r1,#0x00
+Loop1:
+	mov   r2,#0x00
+Loop2:
+	mov r3, r2, lsl#26
+	orr r3, r3, r1, lsl#5
+	mcr p15, 0, r3, c7, c14, 2
+	add r2, r2, #0x01
+	cmp r2, #64
+	bne Loop2
+	add r1, r1, #0x01
+	cmp r1, #8
+	bne Loop1
+
+
+        /*
+         * Initialize the MMU. After we return, the MMU is enabled,
+         * and memory may be remapped. I hope we don't remap this
+         * memory away.
+         */
+        ldr     r0, =mem_map
+        bl      mmu_init
+
+        /*
+         * Initialize the exception vectors. This includes the
+         * exceptions vectors (0x00000000-0x0000001c), and the
+         * pointers to the exception handlers (0x00000020-0x0000003c).
+         */
+        mov     r0, #0
+        adr     r1, vector_block
+        ldmia   r1!, {r2-r9}
+        stmia   r0!, {r2-r9}
+        ldmia   r1!, {r2-r9}
+        stmia   r0!, {r2-r9}
+
+        /* Now we are prepared to start the BSP's C code */
+        mov     r0, #0
+        bl      boot_card
+
+        /*
+         * Theoretically, we could return to what started us up,
+         * but we'd have to have saved the registers and stacks.
+         * Instead, we'll just reset.
+         */
+        bl      bsp_reset
+
+        /* We shouldn't get here. If we do, hang */
+_hang:  b       _hang
+
+
+/*
+ * This is the exception vector table and the pointers to
+ * the functions that handle the exceptions. It's a total
+ * of 16 words (64 bytes)
+ */
+vector_block:
+        ldr     pc, Reset_Handler
+        ldr     pc, Undefined_Handler
+        ldr     pc, SWI_Handler
+        ldr     pc, Prefetch_Handler
+        ldr     pc, Abort_Handler
+        nop
+        ldr     pc, IRQ_Handler
+        ldr     pc, FIQ_Handler
+
+Reset_Handler:          b       bsp_reset
+Undefined_Handler:      b       Undefined_Handler
+SWI_Handler:            b       SWI_Handler
+Prefetch_Handler:       b       Prefetch_Handler
+Abort_Handler:          b       Abort_Handler
+                        nop
+IRQ_Handler:            b       IRQ_Handler
+FIQ_Handler:            b       FIQ_Handler
+
+.globl Reset_Handler
+.globl Undefined_Handler
+.globl SWI_Handler
+.globl Prefetch_Handler
+.globl Abort_Handler
+.globl IRQ_Handler
+.globl FIQ_Handler
diff --git a/c/src/lib/libbsp/arm/smdk2410/startup/bspidle.c b/c/src/lib/libbsp/arm/smdk2410/startup/bspidle.c
new file mode 100644
index 0000000..0f96f1f
--- /dev/null
+++ b/c/src/lib/libbsp/arm/smdk2410/startup/bspidle.c
@@ -0,0 +1,23 @@
+/*
+ *  BSP specific Idle thread
+ */
+
+/*
+ *  Copyright (c) 2000 Canon Research Centre France SA.
+ *  Emmanuel Raguet, mailto:raguet at crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+
+void *bsp_idle_thread(uintptr_t ignored)
+{
+  while(1) {
+    __asm__ volatile ("MCR p15,0,r0,c7,c0,4     \n");
+  }
+  return NULL;
+}
+
diff --git a/c/src/lib/libbsp/arm/smdk2410/startup/bspreset.c b/c/src/lib/libbsp/arm/smdk2410/startup/bspreset.c
index 95ccc42..365a22f 100644
--- a/c/src/lib/libbsp/arm/smdk2410/startup/bspreset.c
+++ b/c/src/lib/libbsp/arm/smdk2410/startup/bspreset.c
@@ -16,7 +16,10 @@ void bsp_reset(void)
 
   SKYEYE_MAGIC_ADDRESS = 0xff;
 #else
-  /* XXX TODO this code is copied from gp32.. move it to a shared place */
+  /* TODO: This code was initially copied from the gp32 BSP. That BSP has
+   * been obsoleted and removed but this code may still benefit from being
+   * in a shared place.
+   */
   rtems_interrupt_level level;
 
   (void) level;
diff --git a/c/src/lib/libbsp/arm/smdk2410/startup/bspstart.c b/c/src/lib/libbsp/arm/smdk2410/startup/bspstart.c
new file mode 100644
index 0000000..5002e57
--- /dev/null
+++ b/c/src/lib/libbsp/arm/smdk2410/startup/bspstart.c
@@ -0,0 +1,89 @@
+/*
+ * This file contains the ARM BSP startup package. It includes application,
+ * board, and monitor specific initialization and configuration. The generic CPU
+ * dependent initialization has been performed before this routine is invoked.
+ */
+
+/*
+ *  Copyright (c) 2000 Canon Research Centre France SA.
+ *  Emmanuel Raguet, mailto:raguet at crf.canon.fr
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <bsp/irq-generic.h>
+#include <rtems/bspIo.h>
+#include <s3c24xx.h>
+
+/*
+ *  BSP Specific Initialization in C
+ */
+static void bsp_start_default( void )
+{
+  uint32_t cr;
+  uint32_t pend,last;
+  uint32_t REFCNT;
+  int i;
+
+  /* stop RTC */
+  #ifdef CPU_S3C2400
+    rTICINT = 0x0;
+  #else
+    rTICNT = 0x0;
+  #endif
+  /* stop watchdog,ADC and timers */
+  rWTCON = 0x0;
+  rTCON = 0x0;
+  rADCCON = 0x0;
+
+  /* disable interrupts */
+  rINTMOD = 0x0;
+  rINTMSK = BIT_ALLMSK; /* unmasked by drivers */
+
+  last = 0;
+  for(i=0; i<4; i++) {
+    pend = rSRCPND;
+    if(pend == 0 || pend == last)
+      break;
+    rSRCPND = pend;
+    rINTPND = pend;
+    last    = pend;
+  }
+
+  /* setup clocks */
+  rCLKDIVN = M_CLKDIVN;
+  rMPLLCON = ((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV);
+  /* setup rREFRESH
+   * period = 15.6 us, HCLK=66Mhz, (2048+1-15.6*66)
+   */
+  REFCNT   = 2048+1-(15.6*get_HCLK()/1000000);
+  rREFRESH = ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT);
+
+  /* set prescaler for timers 2,3,4 to 16(15+1) */
+  cr = rTCFG0 & 0xFFFF00FF;
+  rTCFG0 = (cr | (15<<8));
+
+  /* set prescaler for timers 0,1 to 1(0+1) */
+  cr = rTCFG0 & 0xFFFFFF00;
+  rTCFG0 = (cr | (0<<0));
+
+  /*
+   * Init rtems exceptions management
+   */
+  /* FIXME: Use shared start.S */
+  rtems_exception_init_mngt();
+
+  /*
+   * Init rtems interrupt management
+   */
+  bsp_interrupt_initialize();
+}
+
+/*
+ *  By making this a weak alias for bsp_start_default, a brave soul
+ *  can override the actual bsp_start routine used.
+ */
+void bsp_start (void) __attribute__ ((weak, alias("bsp_start_default")));
diff --git a/c/src/lib/libbsp/arm/smdk2410/startup/memmap.c b/c/src/lib/libbsp/arm/smdk2410/startup/memmap.c
index 0c25263..21ba35b 100644
--- a/c/src/lib/libbsp/arm/smdk2410/startup/memmap.c
+++ b/c/src/lib/libbsp/arm/smdk2410/startup/memmap.c
@@ -1,6 +1,8 @@
 /*
- *  GP32 Memory Map
- *
+ *  SMDK2410 Memory Map
+ */
+
+/*
  *  Copyright (c) 2004 by Cogent Computer Systems
  *  Written by Jay Monkman <jtm at lopingdog.com>
  *
@@ -19,7 +21,7 @@ mmu_sect_map_t mem_map[] = {
     {0x30000000, 0x00000000,   1,   MMU_CACHE_NONE},     /* SDRAM for vectors */
     {0x30000000, 0x30000000,   32,  MMU_CACHE_WTHROUGH}, /* SDRAM W cache */
     {0x32000000, 0x32000000,   32,  MMU_CACHE_NONE},     /* SDRAM W/O cache */
-    {0x48000000, 0x48000000,   256, MMU_CACHE_NONE},    /* Internals Regs - */
-    {0x50000000, 0x50000000,   256, MMU_CACHE_NONE},    /* Internal Regs - */
-    {0x00000000, 0x00000000,   0,    0}                /* The end */
+    {0x48000000, 0x48000000,   256, MMU_CACHE_NONE},     /* Internals Regs - */
+    {0x50000000, 0x50000000,   256, MMU_CACHE_NONE},     /* Internal Regs - */
+    {0x00000000, 0x00000000,   0,    0}                  /* The end */
 };



More information about the vc mailing list