commit 8b59f6f283c08c4df19a2a7838193155d730db58 Author: ricky.wu <[email protected]> Date: Wed Oct 26 22:31:05 2011 +0800 mini2440 bsp for RTEMS 4.10.1 diff --git a/c/src/lib/libbsp/arm/acinclude.m4 b/c/src/lib/libbsp/arm/acinclude.m4 index cd8cd2c..27e5901 100644 --- a/c/src/lib/libbsp/arm/acinclude.m4 +++ b/c/src/lib/libbsp/arm/acinclude.m4 @@ -20,6 +20,8 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR], AC_CONFIG_SUBDIRS([lpc24xx]);; lpc32xx ) AC_CONFIG_SUBDIRS([lpc32xx]);; + mini2440 ) + AC_CONFIG_SUBDIRS([mini2440]);; nds ) AC_CONFIG_SUBDIRS([nds]);; rtl22xx ) diff --git a/c/src/lib/libbsp/arm/mini2440/ChangeLog b/c/src/lib/libbsp/arm/mini2440/ChangeLog new file mode 100644 index 0000000..0080772 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/ChangeLog @@ -0,0 +1,325 @@ +2011-02-02 Ralf Corsépius <[email protected]> + + * configure.ac: Require autoconf-2.68, automake-1.11.1. + +2010-04-30 Sebastian Huber <[email protected]> + + * Makefile.am, preinstall.am: Added generic interrupt support modules. + * include/bsp.h: Define BSP_FEATURE_IRQ_EXTENSION. + * startup/bspstart.c: Interrupt support changes. + +2010-04-30 Sebastian Huber <[email protected]> + + * make/custom/gp32.cfg: Use VFP floating point model. + +2010-04-25 Joel Sherrill <[email protected]> + + * console/uart.c: Fix warnings. + +2010-04-09 Thomas Doerfler <[email protected]> + + * Makefile.am, startup/bspstart.c: make irq data types consistent, + use common code for s3c24xx + +2010-04-07 Joel Sherrill <[email protected]> + + * start/start.S: Verify boot_card() is passed a NULL. + +2010-02-26 Joel Sherrill <[email protected]> + + * smc/smc.c: Replace EBADRQC with EINVAL. + +2010-01-18 Sebastian Huber <[email protected]> + + * smc/smc.c: Update for block device API change. + +2009-10-21 Ralf Corsépius <[email protected]> + + * make/custom/gp32.cfg: Remove RTEMS_BSP_FAMILY. + +2009-10-20 Ralf Corsépius <[email protected]> + + * configure.ac: Don't add -ansi -fasm to CFLAGS. + +2009-10-16 Sebastian Huber <[email protected]> + + * smc/smc.c: Update for block device API change. + +2009-10-15 Ralf Corsépius <[email protected]> + + * make/custom/gp32.cfg: New (relocated from /make/custom). + +2009-09-15 Ralf Corsépius <[email protected]> + + * configure.ac: Remove RTEMS_BSP_BOOTCARD_OPTIONS. + + 2009-08-21 Joel Sherrill <[email protected]> + + * include/bsp.h: Eliminate BSPs defining NUMBER_OF_TERMIOS_PORTS. + Should be automatically handled by confdefs.h or the application. + +2009-07-16 Joel Sherrill <[email protected]> + + * configure.ac: Rename BSP_BOOTCARD_OPTIONS to + RTEMS_BSP_BOOTCARD_OPTIONS. Add RTEMS_BSP_CLEANUP_OPTIONS so all BSPs + have the same options. + +2009-04-28 Chris Johns <[email protected]> + + * start/start.S: Update for boot_card command line change. + +2008-12-04 Joel Sherrill <[email protected]> + + * bsp_specs: Move -e start from *link to *startfile to avoid warning + for undefined entry symbol when linking relocatables with binutils + 2.19. + +2008-10-02 Joel Sherrill <[email protected]> + + * Makefile.am, preinstall.am: Use shared tm27.h stub. + * include/tm27.h: Removed. + +2008-09-29 Ralf Corsépius <[email protected]> + + * Makefile.am: Eliminate bsp.am. Build startup files as side-effect + of building libbspstart.a, using automake-rules. + +2008-09-29 Ralf Corsépius <[email protected]> + + * Makefile.am: Eliminate *_SOURCES. + +2008-09-29 Ralf Corsépius <[email protected]> + + * Makefile.am: Move noinst_LIBRARIES = libbsp.a before its + components. + +2008-09-29 Ralf Corsépius <[email protected]> + + * Makefile.am: Remove noinst_PROGRAMS (Unused). + +2008-09-26 Ralf Corsépius <[email protected]> + + * Makefile.am: Cleanup ../../shared/include/bootcard.h handling. + +2008-09-23 Joel Sherrill <[email protected]> + + * configure.ac: Make letting boot_card() handle work area allocation + mandatory. Rename RTEMS_BSP_BOOTCARD_HANDLES_RAM_ALLOCATION to + BSP_BOOTCARD_OPTIONS. + +2008-09-22 Joel Sherrill <[email protected]> + + * Makefile.am, configure.ac, console/uart.c, startup/bspstart.c: Use + standardized bsp_cleanup() which can optionally print a message, poll + for user to press key, and call bsp_reset(). Using this eliminates + the various bsp_cleanup() implementations which had their own + implementation and variety of string constants. + * startup/bspreset.c: New file. + * startup/bspclean.c: Removed. + +2008-09-19 Joel Sherrill <[email protected]> + + * Makefile.am, startup/linkcmds: Use top level shared + bsp_get_work_area() implementation. + +2008-09-16 Joel Sherrill <[email protected]> + + * startup/bspstart.c: Remove unnecessary includes of + rtems/libcsupport.h and rtems/libio.h. + +2008-09-14 Joel Sherrill <[email protected]> + + * Makefile.am, configure.ac, startup/bspstart.c: Split out + bsp_get_work_area() into its own file and user BSP Framework to + perform more initialization. Use same shared implementation as + edb7312 and csb336. + +2008-08-21 Joel Sherrill <[email protected]> + + * Makefile.am: No BSP should use exit.c as a file name. exit() is POSIX + routine. + * startup/bspclean.c: New file. + * startup/exit.c: Removed. + +2008-08-18 Ralf Corsépius <[email protected]> + + * smc/smc.c, startup/exit.c: Add missing prototypes. + +2008-08-06 Chris Johns <[email protected]> + + * smc/smc.c: Fix the fix. The field is bufnum. + +2008-08-05 Joel Sherrill <[email protected]> + + * smc/smc.c: Fix warning. + +2008-07-29 Chris Johns <[email protected]> + + * smc/smc.c: Updated to the libblock changes. + +2008-05-14 Joel Sherrill <[email protected]> + + * Makefile.am: Rework to avoid .rel files. + +2008-05-12 Joel Sherrill <[email protected]> + + * startup/bspstart.c: Refactored and renamed initialization routines to + rtems_initialize_data_structures, rtems_initialize_before_drivers, + rtems_initialize_device_drivers, and + rtems_initialize_start_multitasking. This opened the sequence up so + that bootcard() could provide a more robust and flexible framework + which is easier to explain and understand. This also lays the + groundwork for sharing the division of available memory between the + RTEMS workspace and heap and the C library initialization across all + BSPs. + +2008-05-06 Ray Xu <[email protected]> + + * console/uart.c, include/bsp.h, smc/smc.c, startup/bspstart.c: Merge + smdk2410 with gp32. + +2008-03-03 Joel Sherrill <[email protected]> + + * startup/linkcmds: Add wildcard to gcc_except_table section so + programs compiled with gcc 4.3.x can link. + +2007-12-11 Joel Sherrill <[email protected]> + + * include/bsp.h, startup/bspstart.c: Fix idle task prototype. + +2007-12-11 Joel Sherrill <[email protected]> + + * include/bsp.h, startup/bspstart.c: Eliminate copies of the + Configuration Table. Use the RTEMS provided accessor macros to obtain + configuration fields. + +2007-12-04 Joel Sherrill <[email protected]> + + * include/bsp.h, startup/bspstart.c: Move interrupt_stack_size field + from CPU Table to Configuration Table. Eliminate CPU Table from all + ports. Delete references to CPU Table in all forms. + +2007-12-03 Joel Sherrill <[email protected]> + + * Makefile.am, include/bsp.h, startup/bspstart.c: Moved most of the + remaining CPU Table fields to the Configuration Table. This included + pretasking_hook, predriver_hook, postdriver_hook, idle_task, + do_zero_of_workspace, extra_mpci_receive_server_stack, + stack_allocate_hook, and stack_free_hook. As a side-effect of this + effort some multiprocessing code was made conditional and some style + clean up occurred. + +2007-09-12 Joel Sherrill <[email protected]> + + PR 1257/bsps + * startup/bspstart.c: Code outside of cpukit should use the public + API for rtems_interrupt_disable/rtems_interrupt_enable. By bypassing + the public API and directly accessing _CPU_ISR_Disable and + _CPU_ISR_Enable, they were bypassing the compiler memory barrier + directive which could lead to problems. This patch also changes the + type of the variable passed into these routines and addresses minor + style issues. + +2007-05-28 Joel Sherrill <[email protected]> + + * startup/bspstart.c: Eliminate maximum_drivers configuration parameter +2007-05-28 Joel Sherrill <[email protected]> + + * startup/bspstart.c: Eliminate maximum_drivers configuration parameter + since it was used to configure a no longer used feature. Device names + are now part of the filesystem not in a table. + +2007-05-15 Ray Xu <[email protected]> + + * Makefile.am: Add abort.rel since it is now in the BSP shared source, + not in score/cpu. + +2007-04-12 Ralf Corsépius <[email protected]> + + * bsp_specs: Remove qrtems_debug. + +2007-03-12 Joel Sherrill <[email protected]> + + * console/uart.c, start/start.S, startup/linkcmds, startup/memmap.c: + Correct license URL and/or fix mistake in copyright notice. Both of + these mistakes appear to be from code submitted after these changes + were made previously. + +2007-03-11 Joel Sherrill <[email protected]> + + * startup/bspstart.c: Remove assignments of + Cpu_table.do_zero_of_workspace to TRUE since TRUE is the default + value in boot_card.c + +2007-02-06 Ralf Corsépius <[email protected]> + + * smc/smc.c: include bspIo.h for printk. + +2006-12-15 Ralf Corsépius <[email protected]> + + * smc/smc.c: Comment out sm_status (unused). + +2006-11-15 Joel Sherrill <[email protected]> + + * Makefile.am: Merge c_rtems_main() into boot_card(). This eliminated a + file and simplified initialization. + +2006-10-17 Ralf Corsépius <[email protected]> + + * Makefile.am: Remove superfluous -DASM. + +2006-10-17 Ralf Corsépius <[email protected]> + + * configure.ac: Require autoconf-2.60. Require automake-1.10. + +2006-09-11 Chris Johns <[email protected]> + + * smc/smc.h: Remove extra CRLF. + +2006-01-11 Ralf Corsepius <[email protected]> + + * Makefile.am: Add preinstall.am. + +2005-11-22 Ralf Corsepius <[email protected]> + + * bsp_specs: remove %lib. + +2005-11-12 Ralf Corsepius <[email protected]> + + * bsp_specs: Remove %cpp. + +2005-07-25 Philippe Simons <[email protected]> + + * Makefile.am: added smc.rel. + * smc/smc.c, smc/smc.h: New files. + +2005-07-07 Philippe Simons <[email protected]> + + * Makefile.am: Remove lcd.rel, added console/uart.c, + removed conio stuffs. + * console/conio.c, console/console.c, console/defaultfont.c, + include/conio.h : files removed. + * console/uart.c: New file. + * include/bsp.h: lcd.c prototypes removed. + * startup/bspstart.c: bsp_reset() cause gp32 to reset to bios, + added a bsp_idle_task which put s3c2400 in a "wait for IRQ" state. + +2005-06-06 Philippe Simons <[email protected]> + + * Makefile.am: Include lcd.rel. + +2005-06-01 Philippe Simons <[email protected]> + + * bsp_specs: Add rules for cpp support + * include/bsp.h: Add gp32 support fct prototypes + * console/conio.c: Moved video buffer to 0x0c7ed000 + * startup/bspstart.c: Add some init code, some cleaning... + +2005-05-26 Ralf Corsepius <[email protected]> + + * include/bsp.h: New header guard. + +2005-04-26 Joel Sherrill <[email protected]> + + * startup/bspstart.c: Add include rtems/bspIo.h to eliminate warning. + diff --git a/c/src/lib/libbsp/arm/mini2440/Makefile.am b/c/src/lib/libbsp/arm/mini2440/Makefile.am new file mode 100644 index 0000000..eb6fb7f --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/Makefile.am @@ -0,0 +1,74 @@ +## +## $Id: Makefile.am,v 1.24 2010/04/30 14:30:09 sh Exp $ +## + +ACLOCAL_AMFLAGS = -I ../../../../aclocal + +include $(top_srcdir)/../../../../automake/compile.am + +include_bspdir = $(includedir)/bsp + +dist_project_lib_DATA = bsp_specs + +include_HEADERS = include/bsp.h +include_HEADERS += smc/smc.h +include_HEADERS += ../../shared/include/tm27.h + +include_bsp_HEADERS = + +nodist_include_HEADERS = include/bspopts.h +nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h +DISTCLEANFILES = include/bspopts.h + +nodist_include_HEADERS += ../../shared/include/coverhd.h + +noinst_LIBRARIES = libbspstart.a +libbspstart_a_SOURCES = start/start.S +project_lib_DATA = start.$(OBJEXT) + +dist_project_lib_DATA += startup/linkcmds + +noinst_LIBRARIES += libbsp.a +libbsp_a_SOURCES = + +# startup +libbsp_a_SOURCES += ../../shared/bsplibc.c ../../shared/bsppost.c \ + ../../shared/bsppredriverhook.c ../../shared/bspgetworkarea.c \ + ../../shared/bsppretaskinghook.c startup/bspstart.c \ + ../../shared/bspclean.c startup/bspreset.c \ + startup/memmap.c ../../shared/bootcard.c ../../shared/sbrk.c \ + ../../shared/gnatinstallhandler.c +# console +libbsp_a_SOURCES += console/uart.c ../../shared/console.c +# IRQ +include_bsp_HEADERS += ../../shared/include/irq-generic.h \ + ../../shared/include/irq-info.h +libbsp_a_SOURCES += ../../shared/src/irq-generic.c \ + ../../shared/src/irq-legacy.c \ + ../../shared/src/irq-info.c \ + ../../shared/src/irq-shell.c \ + ../../shared/src/irq-server.c +# abort +libbsp_a_SOURCES += ../shared/abort/abort.c +# smc +libbsp_a_SOURCES += smc/smc.c smc/smc.h + +if HAS_NETWORKING +network_CPPFLAGS = -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ +noinst_PROGRAMS = network.rel +network_rel_SOURCES = network/network.c +network_rel_CPPFLAGS = $(AM_CPPFLAGS) $(network_CPPFLAGS) +network_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) +endif + +libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/shared/arm920.rel \ + ../../../libcpu/@RTEMS_CPU@/s3c24xx/clock.rel \ + ../../../libcpu/@RTEMS_CPU@/s3c24xx/timer.rel \ + ../../../libcpu/@RTEMS_CPU@/s3c24xx/irq.rel + +if HAS_NETWORKING +libbsp_a_LIBADD += network.rel +endif + +include $(srcdir)/preinstall.am +include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/arm/mini2440/README b/c/src/lib/libbsp/arm/mini2440/README new file mode 100644 index 0000000..139597f --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/README @@ -0,0 +1,2 @@ + + diff --git a/c/src/lib/libbsp/arm/mini2440/bsp_specs b/c/src/lib/libbsp/arm/mini2440/bsp_specs new file mode 100644 index 0000000..082653a --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/bsp_specs @@ -0,0 +1,13 @@ +%rename endfile old_endfile +%rename startfile old_startfile +%rename link old_link + +*startfile: +%{!qrtems: %(old_startfile)} \ +%{!nostdlib: %{qrtems: start.o%s crti.o%s crtbegin.o%s -e _start}} + +*link: +%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N} + +*endfile: +%{!qrtems: *(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s } diff --git a/c/src/lib/libbsp/arm/mini2440/configure.ac b/c/src/lib/libbsp/arm/mini2440/configure.ac new file mode 100644 index 0000000..da53c13 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/configure.ac @@ -0,0 +1,25 @@ +## Process this file with autoconf to produce a configure script. +## +## configure.ac,v 1.5 2003/03/11 09:39:07 ralf Exp + +AC_PREREQ([2.65]) +AC_INIT([rtems-c-src-lib-libbsp-arm-gp32],[_RTEMS_VERSION],[[email protected]]) +AC_CONFIG_SRCDIR([bsp_specs]) +RTEMS_TOP(../../../../../..) + +RTEMS_CANONICAL_TARGET_CPU +AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.11.1]) +RTEMS_BSP_CONFIGURE + +RTEMS_PROG_CC_FOR_TARGET +RTEMS_CANONICALIZE_TOOLS +RTEMS_PROG_CCAS + +RTEMS_CHECK_NETWORKING +AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes") + +RTEMS_BSP_CLEANUP_OPTIONS(0, 1) + +# Explicitly list all Makefiles here +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/c/src/lib/libbsp/arm/mini2440/console/uart.c b/c/src/lib/libbsp/arm/mini2440/console/uart.c new file mode 100644 index 0000000..9ba6e41 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/console/uart.c @@ -0,0 +1,253 @@ +/* + * 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) 2011 RickLeaf + * Written by Ricky Wu <[email protected]> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * + * $Id: uart.c,v 1.6 2010/04/26 02:33:57 joel Exp $ +*/ +#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_Port_Count = NUM_DEVS; +console_data Console_Port_Data[NUM_DEVS]; + +/* rtems console uses the following minor number */ +rtems_device_minor_number Console_Port_Minor = 0; + +/* Pointers to functions for handling the UART. */ +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_Port_Tbl[] = { + { + "/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 * 38400) - 1; + + /* FIFO enable, Tx/Rx FIFO clear */ + rUFCON0 = 0x0; + 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/mini2440/include/bsp.h b/c/src/lib/libbsp/arm/mini2440/include/bsp.h new file mode 100644 index 0000000..7ddc7c1 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/include/bsp.h @@ -0,0 +1,91 @@ +/*-------------------------------------------------------------------------+ +| bsp.h - ARM BSP ++--------------------------------------------------------------------------+ +| This include file contains definitions related to the ARM BSP. ++--------------------------------------------------------------------------+ +| +| Copyright (c) Ricky Wu mailto:[email protected] +| +| The license and distribution terms for this file may be +| found in found in the file LICENSE in this distribution or at +| http://www.rtems.com/license/LICENSE. +| +| $Id: bsp.h,v 1.13 2010/04/30 14:30:09 sh Exp $ ++--------------------------------------------------------------------------*/ + + +#ifndef _BSP_H +#define _BSP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <bspopts.h> + +#include <rtems.h> +#include <rtems/iosupp.h> +#include <rtems/console.h> +#include <rtems/clockdrv.h> +#include <s3c24xx.h> + +#define BSP_FEATURE_IRQ_EXTENSION + +#define gp32_initButtons() {rPBCON=0x0;} +#define gp32_getButtons() \ + ( (((~rPEDAT >> 6) & 0x3 )<<8) | (((~rPBDAT >> 8) & 0xFF)<<0) ) + +/*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); + + +void gp32_setPalette( unsigned char pos, uint16_t color); + +/* What is the input clock freq in hertz? */ +#define BSP_OSC_FREQ 12000000 /* 12 MHz oscillator */ +#define M_MDIV 92 /* FCLK=400Mhz */ +#define M_PDIV 1 +#define M_SDIV 1 +#define M_CLKDIVN 3 /* HCLK=PCLK/2, PCLK=FCLK/4 */ + +#define REFEN 0x1 /* enable refresh */ +#define TREFMD 0x0 /* CBR(CAS before RAS)/auto refresh */ +#define Trp 0x0 /* 2 clk */ +#define Trc 0x3 /* 7 clk */ +#define Tchr 0x2 /* 3 clk */ + + +/* How many serial ports? */ +#define CONFIGURE_NUMBER_OF_TERMIOS_PORTS 1 + +/* + * This BSP provides its own IDLE task to override the RTEMS one. + * So we prototype it and define the constant confdefs.h expects + * to configure a BSP specific one. + */ +Thread bsp_idle_task(uint32_t); + +#define BSP_IDLE_TASK_BODY bsp_idle_task + + +/* + * Network driver configuration + */ +extern struct rtems_bsdnet_ifconfig *config; + +/* Change these to match your board */ +int rtems_dm9000_attach(struct rtems_bsdnet_ifconfig *config, int attaching); +#define RTEMS_BSP_NETWORK_DRIVER_NAME "eth0" +#define RTEMS_BSP_NETWORK_DRIVER_ATTACH rtems_dm9000_attach + + + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_H */ + diff --git a/c/src/lib/libbsp/arm/mini2440/make/custom/mini2440.cfg b/c/src/lib/libbsp/arm/mini2440/make/custom/mini2440.cfg new file mode 100644 index 0000000..01e6f28 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/make/custom/mini2440.cfg @@ -0,0 +1,23 @@ +# +# Config file for ARM smdk2410 +# +# $Id: mini2440.cfg,v 1.3 2010/04/30 13:40:13 sh Exp $ +# + +include $(RTEMS_ROOT)/make/custom/default.cfg + +RTEMS_CPU=arm +RTEMS_CPU_MODEL=s3c2440 + +# This contains the compiler options necessary to select the CPU model +# and (hopefully) optimize for it. +CPU_CFLAGS = -mstructure-size-boundary=32 -mcpu=arm920t -mfpu=vfp -mfloat-abi=soft -DCPU_S3C2440 + +# optimize flag: typically -O2 +CFLAGS_OPTIMIZE_V = -O2 -g + +define bsp-post-link + $(OBJCOPY) -O binary $(basename $@).exe $(basename $@)$(DOWNEXT) + $(default-bsp-post-link) +endef + diff --git a/c/src/lib/libbsp/arm/mini2440/network/network.c b/c/src/lib/libbsp/arm/mini2440/network/network.c new file mode 100644 index 0000000..0f3c3ab --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/network/network.c @@ -0,0 +1,1255 @@ +/***************************************************************************** + +It's mini2440 network driver. (DM9000EP) +version:1.0 + +Bacon Xu [email protected] +2011.3.23 + + + +******************************************************************************/ + + +#include <rtems.h> +#include <rtems/rtems_bsdnet.h> +#include <stdio.h> +#include <string.h> + +#include <errno.h> +#include <rtems/error.h> + +#include <sys/param.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/sockio.h> + +#include <net/if.h> + +#include <netinet/in.h> +#include <netinet/if_ether.h> + +#include <bsp/irq.h> + +/* +It's micro for DM9000 +*/ +/* + * dm9000 Ethernet + */ + +#define DM9000_ID 0x90000A46 +#define DM9000_PKT_MAX 1536 /* Received packet max size */ +#define DM9000_PKT_RDY 0x01 /* Packet ready to receive */ + +/* although the registers are 16 bit, they are 32-bit aligned. + */ + +#define DM9000_NCR 0x00 +#define DM9000_NSR 0x01 +#define DM9000_TCR 0x02 +#define DM9000_TSR1 0x03 +#define DM9000_TSR2 0x04 +#define DM9000_RCR 0x05 +#define DM9000_RSR 0x06 +#define DM9000_ROCR 0x07 +#define DM9000_BPTR 0x08 +#define DM9000_FCTR 0x09 +#define DM9000_FCR 0x0A +#define DM9000_EPCR 0x0B +#define DM9000_EPAR 0x0C +#define DM9000_EPDRL 0x0D +#define DM9000_EPDRH 0x0E +#define DM9000_WCR 0x0F + +#define DM9000_PAR 0x10 +#define DM9000_MAR 0x16 + +#define DM9000_GPCR 0x1e +#define DM9000_GPR 0x1f +#define DM9000_TRPAL 0x22 +#define DM9000_TRPAH 0x23 +#define DM9000_RWPAL 0x24 +#define DM9000_RWPAH 0x25 + +#define DM9000_VIDL 0x28 +#define DM9000_VIDH 0x29 +#define DM9000_PIDL 0x2A +#define DM9000_PIDH 0x2B + +#define DM9000_CHIPR 0x2C +#define DM9000_SMCR 0x2F + +#define DM9000_PHY 0x40 /* PHY address 0x01 */ + +#define DM9000_MRCMDX 0xF0 +#define DM9000_MRCMD 0xF2 +#define DM9000_MRRL 0xF4 +#define DM9000_MRRH 0xF5 +#define DM9000_MWCMDX 0xF6 +#define DM9000_MWCMD 0xF8 +#define DM9000_MWRL 0xFA +#define DM9000_MWRH 0xFB +#define DM9000_TXPLL 0xFC +#define DM9000_TXPLH 0xFD +#define DM9000_ISR 0xFE +#define DM9000_IMR 0xFF + +#define NCR_EXT_PHY (1<<7) +#define NCR_WAKEEN (1<<6) +#define NCR_FCOL (1<<4) +#define NCR_FDX (1<<3) +#define NCR_LBK (3<<1) +#define NCR_LBK_INT_MAC (1<<1) +#define NCR_LBK_INT_PHY (2<<1) +#define NCR_RST (1<<0) + +#define NSR_SPEED (1<<7) +#define NSR_LINKST (1<<6) +#define NSR_WAKEST (1<<5) +#define NSR_TX2END (1<<3) +#define NSR_TX1END (1<<2) +#define NSR_RXOV (1<<1) + +#define TCR_TJDIS (1<<6) +#define TCR_EXCECM (1<<5) +#define TCR_PAD_DIS2 (1<<4) +#define TCR_CRC_DIS2 (1<<3) +#define TCR_PAD_DIS1 (1<<2) +#define TCR_CRC_DIS1 (1<<1) +#define TCR_TXREQ (1<<0) + +#define TSR_TJTO (1<<7) +#define TSR_LC (1<<6) +#define TSR_NC (1<<5) +#define TSR_LCOL (1<<4) +#define TSR_COL (1<<3) +#define TSR_EC (1<<2) + +#define RCR_WTDIS (1<<6) +#define RCR_DIS_LONG (1<<5) +#define RCR_DIS_CRC (1<<4) +#define RCR_ALL (1<<3) +#define RCR_RUNT (1<<2) +#define RCR_PRMSC (1<<1) +#define RCR_RXEN (1<<0) + +#define RSR_RF (1<<7) +#define RSR_MF (1<<6) +#define RSR_LCS (1<<5) +#define RSR_RWTO (1<<4) +#define RSR_PLE (1<<3) +#define RSR_AE (1<<2) +#define RSR_CE (1<<1) +#define RSR_FOE (1<<0) + +#define EPCR_EPOS_PHY (1<<3) +#define EPCR_EPOS_EE (0<<3) +#define EPCR_ERPRR (1<<2) +#define EPCR_ERPRW (1<<1) +#define EPCR_ERRE (1<<0) + +#define FCTR_HWOT(ot) (( (ot) & 0xf ) << 4 ) +#define FCTR_LWOT(ot) ( (ot) & 0xf ) + +#define BPTR_BPHW(x) ((x) << 4) +#define BPTR_JPT_200US (0x07) +#define BPTR_JPT_600US (0x0f) + +#define IMR_PAR (1<<7) +#define IMR_ROOM (1<<3) +#define IMR_ROM (1<<2) +#define IMR_PTM (1<<1) +#define IMR_PRM (1<<0) + +#define ISR_ROOS (1<<3) +#define ISR_ROS (1<<2) +#define ISR_PTS (1<<1) +#define ISR_PRS (1<<0) + +#define GPCR_GPIO0_OUT (1<<0) + +#define GPR_PHY_PWROFF (1<<0) +/* RTEMS event used by interrupt handler to start receive daemon. */ +#define START_RECEIVE_EVENT RTEMS_EVENT_1 + +/* RTEMS event used to start transmit daemon. */ +#define START_TRANSMIT_EVENT RTEMS_EVENT_2 + + + +/* DM9000 network board routine ---------------------------- */ + +#define DM9000_outb(d,r) (*(volatile uint8_t *)r = d) +#define DM9000_outw(d,r) (*(volatile uint16_t *)r = d) +#define DM9000_outl(d,r) (*(volatile uint32_t *)r = d) +#define DM9000_inb(r) (*(volatile uint8_t *)r) +#define DM9000_inw(r) (*(volatile uint16_t *)r) +#define DM9000_inl(r) (*(volatile uint32_t *)r) +#define __le16_to_cpu(x) ((uint16_t)(x)) + +/* #define CONFIG_DM9000_DEBUG */ + +#ifdef CONFIG_DM9000_DEBUG +#define DM9000_DBG(fmt,args...) printf(fmt, ##args) +#define DM9000_DMP_PACKET(func,packet,length) \ + do { \ + int i; \ + printf(func ": length: %d\n", length); \ + for (i = 0; i < length; i++) { \ + if (i % 8 == 0) \ + printf("\n%s: %02x: ", func, i); \ + printf("%02x ", ((unsigned char *) packet)[i]); \ + } printf("\n"); \ + } while(0) +#else +#define DM9000_DBG(fmt,args...) +#define DM9000_DMP_PACKET(func,packet,length) +#endif + + +#define CONFIG_DRIVER_DM9000 1 +#define CONFIG_DM9000_BASE 0x20000300 +#define DM9000_IO CONFIG_DM9000_BASE +#define DM9000_DATA (CONFIG_DM9000_BASE + 4) + + +/* +#define CONFIG_NET_POLL_CONTROLLER +*/ +/* +#define CONFIG_DM9000_USE_8BIT +*/ +#define CONFIG_DM9000_USE_16BIT +/* +#define CONFIG_DM9000_USE_32BIT +*/ +#define CONFIG_DM9000_MAC_ADDR_H 0x0012 +#define CONFIG_DM9000_MAC_ADDR_L 0x34567800 + + + +/***************************************************************************** + +global type for dm9000 + +*****************************************************************************/ +/* + * Hardware-specific storage + */ +typedef struct +{ + /* + * Connection to networking code + * This entry *must* be the first in the sonic_softc structure. + */ + struct arpcom arpcom; + /* + * Interrupt vector + */ + rtems_vector_number vector; + /* + * Indicates configuration + */ + int acceptBroadcast; + /* + * Task waiting for interrupts + */ + rtems_id rxDaemonTid; + rtems_id txDaemonTid; + + uint32_t (*outmbuf)(struct mbuf *); + void (*outblk)(volatile void *, int); + void (*inblk)(void *, int); + void (*rx_status)(uint16_t *, uint16_t *); +#if 0 + /* + * Statistics + */ + unsigned long Interrupts; + unsigned long rxInterrupts; + unsigned long rxMissed; + unsigned long rxGiant; + unsigned long rxNonOctet; + unsigned long rxBadCRC; + unsigned long rxCollision; + + unsigned long txInterrupts; + unsigned long txSingleCollision; + unsigned long txMultipleCollision; + unsigned long txCollision; + unsigned long txDeferred; + unsigned long txUnderrun; + unsigned long txLateCollision; + unsigned long txExcessiveCollision; + unsigned long txExcessiveDeferral; + unsigned long txLostCarrier; + unsigned long txRawWait; +#endif +} dm9000_softc_t; + +/***************************************************************************** + +internal variables. + +*****************************************************************************/ +static dm9000_softc_t softc; + + +/***************************************************************************** + +internal functions + +*****************************************************************************/ +static uint32_t dm9000_outmbuf_8bit(struct mbuf *m); +static uint32_t dm9000_outmbuf_16bit(struct mbuf *m); +static uint32_t dm9000_outmbuf_32bit(struct mbuf *m); +static void dm9000_outblk_8bit(volatile void *data_ptr, int count); +static void dm9000_outblk_16bit(volatile void *data_ptr, int count); +static void dm9000_outblk_32bit(volatile void *data_ptr, int count); +static void dm9000_inblk_8bit(void *data_ptr, int count); +static void dm9000_inblk_16bit(void *data_ptr, int count); +static void dm9000_inblk_32bit(void *data_ptr, int count); +static void dm9000_rx_status_32bit(uint16_t *RxStatus, uint16_t *RxLen); +static void dm9000_rx_status_16bit(uint16_t *RxStatus, uint16_t *RxLen); +static void dm9000_rx_status_8bit(uint16_t *RxStatus, uint16_t *RxLen); +static uint8_t DM9000_ior(int reg); +static void DM9000_iow(int reg, uint8_t value); +static uint16_t phy_read(int reg); +static void phy_write(int reg, uint16_t value); +static void udelay(uint32_t us); +#ifdef CONFIG_DM9000_DEBUG +static void dump_regs(void); +#endif +static int dm9000_set_mac(dm9000_softc_t *sc); +static void dm9000_reset(void); +static int dm9000_probe(void); + +void dm9000_init(void *arg); +int dm9000_init_hw(dm9000_softc_t *sc); +void dm9000_start(struct ifnet *ifp); +void dm9000_stop(dm9000_softc_t *sc); +void dm9000_txDaemon(void *arg); +void dm9000_sendpacket(dm9000_softc_t *sc, struct mbuf *m); +void dm9000_rxDaemon(void *arg); +void dm9000_stats (dm9000_softc_t *sc); +static void dm9000_isr_on(const rtems_irq_connect_data *unused); +static void dm9000_isr_off(const rtems_irq_connect_data *unused); +static int dm9000_isr_is_on(const rtems_irq_connect_data *irq); +rtems_isr dm9000_isr (rtems_vector_number v); +static int dm9000_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data); + +/* Replace the first value with the clock's interrupt name. */ +rtems_irq_connect_data dm9000_isr_data = { + BSP_EINT4_7, + (rtems_irq_hdl)dm9000_isr, + dm9000_isr_on, + dm9000_isr_off, + dm9000_isr_is_on, + 3, /* unused for ARM */ + 0 }; /* unused for ARM */ + +/***************************************************************************** + +*****************************************************************************/ +int rtems_dm9000_attach ( + struct rtems_bsdnet_ifconfig *config, + void *chip /* only one ethernet, so no chip number */ + ) +{ + struct ifnet *ifp; + int mtu; + int unitnumber; + char *unitname; + + /* + * Parse driver name + */ + if ((unitnumber = rtems_bsdnet_parse_driver_name (config, &unitname)) < 0) + return 0; + + /* + * Is driver free? + */ + if (unitnumber != 0) { + printf ("Bad DM9000 unit number.\n"); + return 0; + } + + ifp = &softc.arpcom.ac_if; + if (ifp->if_softc != NULL) { + printf ("Driver already in use.\n"); + return 0; + } + + /* + * zero out the control structure + */ + + memset( &softc, 0, sizeof(softc) ); + + + /* get the MAC address from the chip */ + softc.arpcom.ac_enaddr[0] = 0x00; + softc.arpcom.ac_enaddr[1] = 0x00; + softc.arpcom.ac_enaddr[2] = 0x01; + softc.arpcom.ac_enaddr[3] = 0x23; + softc.arpcom.ac_enaddr[4] = 0x45; + softc.arpcom.ac_enaddr[5] = 0x00; + + + if (config->mtu) { + mtu = config->mtu; + } else { + mtu = ETHERMTU; + } + + softc.acceptBroadcast = !config->ignore_broadcast; + + /* + * Set up network interface values + */ + ifp->if_softc = &softc; + ifp->if_unit = unitnumber; + ifp->if_name = unitname; + ifp->if_mtu = mtu; + ifp->if_init = dm9000_init; + ifp->if_ioctl = dm9000_ioctl; + ifp->if_start = dm9000_start; + ifp->if_output = ether_output; + ifp->if_flags = IFF_BROADCAST; + if (ifp->if_snd.ifq_maxlen == 0) { + ifp->if_snd.ifq_maxlen = ifqmaxlen; + } + + /* + * Attach the interface + */ + if_attach (ifp); + ether_ifattach (ifp); + return 1; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +rtems_id gID; +rtems_name gName; + +rtems_task dm9000_poll_task(rtems_task_argument ignored) +{ + while (1) + { + dm9000_isr(1); + rtems_task_wake_after(5); + } +} +#endif + +void dm9000_init(void *arg) +{ + dm9000_softc_t *sc = arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + + /* + *This is for stuff that only gets done once (at91rm9200_emac_init() + * gets called multiple times + */ + if (sc->txDaemonTid == 0) { + /* Set up EMAC hardware */ + dm9000_init_hw(sc); + + /* Start driver tasks */ + sc->rxDaemonTid = rtems_bsdnet_newproc("ENrx", + 4096, + dm9000_rxDaemon, + sc); + sc->txDaemonTid = rtems_bsdnet_newproc("ENtx", + 4096, + dm9000_txDaemon, + sc); +#ifdef CONFIG_NET_POLL_CONTROLLER + gName = rtems_build_name('D', 'E', 'A', 'M'); + rtems_task_create(gName, 1, RTEMS_MINIMUM_STACK_SIZE * 2, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &gID); + rtems_task_start(gID, dm9000_poll_task, 1); +#endif + } /* if txDaemonTid */ + +#if !defined(CONFIG_NET_POLL_CONTROLLER) + /* install the interrupt handler */ + BSP_install_rtems_irq_handler(&dm9000_isr_data); +#endif + + /* EMAC doesn't support promiscuous, so ignore requests */ + if (ifp->if_flags & IFF_PROMISC) { + printf ("Warning - DM9000 Ethernet driver" + " doesn't support Promiscuous Mode!\n"); + } + + /* + * Tell the world that we're running. + */ + ifp->if_flags |= IFF_RUNNING; +} + +int dm9000_init_hw(dm9000_softc_t *sc) +{ + uint8_t io_mode; + int i, lnk; + + /* RESET device */ + dm9000_reset(); + + if (dm9000_probe() < 0) + return -1; + + /* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */ +#if defined(CONFIG_DM9000_USE_16BIT) + io_mode = 0; +#else + io_mode = DM9000_ior(DM9000_ISR) >> 6; +#endif + + switch (io_mode) { + case 0x0: /* 16-bit mode */ + printf("DM9000: running in 16 bit mode\n"); + sc->outmbuf = dm9000_outmbuf_16bit; + sc->outblk = dm9000_outblk_16bit; + sc->inblk = dm9000_inblk_16bit; + sc->rx_status = dm9000_rx_status_16bit; + break; + case 0x01: /* 32-bit mode */ + printf("DM9000: running in 32 bit mode\n"); + sc->outmbuf = dm9000_outmbuf_32bit; + sc->outblk = dm9000_outblk_32bit; + sc->inblk = dm9000_inblk_32bit; + sc->rx_status = dm9000_rx_status_32bit; + break; + case 0x02: /* 8 bit mode */ + printf("DM9000: running in 8 bit mode\n"); + sc->outmbuf = dm9000_outmbuf_8bit; + sc->outblk = dm9000_outblk_8bit; + sc->inblk = dm9000_inblk_8bit; + sc->rx_status = dm9000_rx_status_8bit; + break; + default: + /* Assume 8 bit mode, will probably not work anyway */ + printf("DM9000: Undefined IO-mode:0x%x\n", io_mode); + sc->outmbuf = dm9000_outmbuf_8bit; + sc->outblk = dm9000_outblk_8bit; + sc->inblk = dm9000_inblk_8bit; + sc->rx_status = dm9000_rx_status_8bit; + break; + } + + /* Program operating register, only internal phy supported */ + DM9000_iow(DM9000_NCR, 0x0); + /* TX Polling clear */ + DM9000_iow(DM9000_TCR, 0); + /* Less 3Kb, 200us */ + DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_200US); + /* Flow Control : High/Low Water */ + DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); + /* SH FIXME: This looks strange! Flow Control */ + DM9000_iow(DM9000_FCR, 0x0); + /* Special Mode */ + DM9000_iow(DM9000_SMCR, 0); + /* clear TX status */ + DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); + /* Clear interrupt status */ + DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); + + /*set mac address*/ + dm9000_set_mac(sc); + + /* Activate DM9000 */ + /* RX enable */ + DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); + /* Enable TX/RX interrupt mask */ + DM9000_iow(DM9000_IMR, IMR_PAR | IMR_PRM); + + + /* PHY read status doesn't work anyway*/ +#if !defined(CONFIG_MINI2440) + return 0; +#endif + i = 0; + while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */ + udelay(1000); + i++; + if (i == 10000) { + printf("could not establish link\n"); + return 0; + } + } + + /* see what we've got */ + lnk = phy_read(17) >> 12; + printf("operating at "); + switch (lnk) { + case 1: + printf("10M half duplex "); + break; + case 2: + printf("10M full duplex "); + break; + case 4: + printf("100M half duplex "); + break; + case 8: + printf("100M full duplex "); + break; + default: + printf("unknown: %d ", lnk); + break; + } + printf("mode\n"); + return 0; +} + +void dm9000_start(struct ifnet *ifp) +{ + dm9000_softc_t *sc = ifp->if_softc; + + rtems_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT); + ifp->if_flags |= IFF_OACTIVE; +} + +void dm9000_stop (dm9000_softc_t *sc) +{ + struct ifnet *ifp = &sc->arpcom.ac_if; + + ifp->if_flags &= ~IFF_RUNNING; + + /* + * Stop the transmitter and receiver. + */ + DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */ +} + +/* + * Driver transmit daemon + */ +void dm9000_txDaemon (void *arg) +{ + dm9000_softc_t *sc = (dm9000_softc_t *)arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + struct mbuf *m; + rtems_event_set events; + + for (;;) + { + /* turn on TX interrupt, then wait for one */ + rtems_bsdnet_event_receive( + START_TRANSMIT_EVENT, + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events); + + /* Send packets till queue is empty */ + for (;;) + { + /* Get the next mbuf chain to transmit. */ + IF_DEQUEUE(&ifp->if_snd, m); + if (!m) + break; + dm9000_sendpacket(sc, m); + } + ifp->if_flags &= ~IFF_OACTIVE; + } +} + +/* Send packet */ +void dm9000_sendpacket(dm9000_softc_t *sc, struct mbuf *m) +{ + unsigned int length = 0; + rtems_interval tmo; +#if 0 + struct mbuf *l; + static uint8_t packet[2000]; + + /* copy the mbuf chain into the transmit buffer */ + l = m; + while (l != NULL) { + memcpy(((char *)packet + length), /* offset into pkt for mbuf */ + (char *)mtod(l, void *), /* cast to void */ + l->m_len); /* length of this mbuf */ + + length += l->m_len; /* update offset */ + l = l->m_next; /* get next mbuf, if any */ + } + + /* free the mbuf chain we just copied */ + m_freem(m); + + DM9000_DMP_PACKET("eth_send", packet, length); + + /* Move data to DM9000 TX RAM */ + DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */ + + /* push the data to the TX-fifo */ + (sc->outblk)(packet, length); +#else + /* Move data to DM9000 TX RAM */ + DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */ + + length = (sc->outmbuf)(m); + + m_freem(m); +#endif + + /* Set TX length to DM9000 */ + DM9000_iow(DM9000_TXPLL, length & 0xff); + DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff); + + /* Issue TX polling command */ + DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ + + /* wait for end of transmission */ + tmo = rtems_clock_get_ticks_since_boot() + 5 * rtems_clock_get_ticks_per_second(); + while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || + !(DM9000_ior(DM9000_ISR) & IMR_PTM) ) { + if (rtems_clock_get_ticks_since_boot() >= tmo) + { + printf("transmission timeout\n"); + break; + } + } + DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ + + DM9000_DBG("transmit done\n\n"); +} + + +/* dm9000 reader task */ +void dm9000_rxDaemon(void *arg) +{ + dm9000_softc_t *sc = (dm9000_softc_t *)arg; + struct ifnet *ifp = &sc->arpcom.ac_if; + struct mbuf *m; + struct ether_header *eh; + rtems_event_set events; + uint8_t rxbyte; + uint16_t RxStatus, RxLen = 0; + + /* Input packet handling loop */ + for (;;) { + rtems_bsdnet_event_receive( + START_RECEIVE_EVENT, + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events); + + /* There is _at least_ 1 package in the fifo, read them all */ + for (;;) { + /* get an mbuf this packet */ + MGETHDR(m, M_WAIT, MT_DATA); + + /* now get a cluster pointed to by the mbuf */ + /* since an mbuf by itself is too small */ + MCLGET(m, M_WAIT); + + /* set the type of mbuf to ifp (ethernet I/F) */ + m->m_pkthdr.rcvif = ifp; + m->m_nextpkt = 0; + + DM9000_ior(DM9000_MRCMDX); /* Dummy read */ + + /* Get most updated data, + only look at bits 0:1, See application notes DM9000 */ + rxbyte = DM9000_inb(DM9000_DATA) & 0x03; + + /* Status check: this byte must be 0 or 1 */ + if (rxbyte > DM9000_PKT_RDY) { + DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */ + DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */ + printf("DM9000 error: status check fail: 0x%x\n", + rxbyte); + m_freem(m); + rtems_task_wake_after(2 * rtems_clock_get_ticks_per_second()); + dm9000_init_hw(sc); + break; + } + + if (rxbyte != DM9000_PKT_RDY) + { + m_freem(m); + break; /* No packet received, ignore */ + } + DM9000_DBG("receiving packet\n"); + + DM9000_outb(DM9000_MWCMD, DM9000_IO); + /* A packet ready now & Get status/length */ + (sc->rx_status)(&RxStatus, &RxLen); + + DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); + + if ((RxStatus & 0xbf00) || (RxLen < 0x40) + || (RxLen > DM9000_PKT_MAX)) { + if (RxStatus & 0x100) { + printf("rx fifo error\n"); + } + if (RxStatus & 0x200) { + printf("rx crc error\n"); + } + if (RxStatus & 0x8000) { + printf("rx length error\n"); + } + if (RxLen > DM9000_PKT_MAX) { + printf("rx length too big\n"); + /*dm9000_reset();*/ + dm9000_init_hw(sc); + } + m_freem(m); + } else { + /* Move data from DM9000 */ + /* Read received packet from RX SRAM */ + (sc->inblk)(m->m_ext.ext_buf, RxLen); + DM9000_DMP_PACKET("eth_rx", rdptr, RxLen); + + DM9000_DBG("passing packet to upper layer\n"); + + /* set the length of the mbuf */ + m->m_len = RxLen - (sizeof(struct ether_header) + 4); + m->m_pkthdr.len = m->m_len; + + /* strip off the ethernet header from the mbuf */ + /* but save the pointer to it */ + eh = mtod (m, struct ether_header *); + m->m_data += sizeof(struct ether_header); + ether_input(ifp, eh, m); + } + } + } /* for (;;) */ +} + +/* Show interface statistics */ +void dm9000_stats (dm9000_softc_t *sc) +{ + printf("dm9000_stats isn't sound.\n"); +} + +static void dm9000_isr_on(const rtems_irq_connect_data *unused) +{ + + rEXTINT0 = 0x12222222; + /*Initialize the interrupt, mini2440 eint7*/ + /*eint4_7 use irq mode*/ + rINTMOD &= (~BIT_EINT4_7); + /*enable eint7, io -> eint7*/ + rGPFCON = ((rGPFCON & 0x3FFF) | (0x2 << 14)); + /*enable eint7*/ + rEINTMASK &= (~0x80); + /*enable eint4-7*/ + rINTMSK &= (~BIT_EINT4_7); + return; +} + + +static void dm9000_isr_off(const rtems_irq_connect_data *unused) +{ + /* disable all various TX/RX interrupts */ + rINTMSK |= BIT_EINT4_7; + rEINTMASK |= 0x80; + return; +} + +/* Tests to see if dm9000 interrupts are enabled, and + * returns non-0 if so. + * If interrupt is not enabled, returns 0. + */ +static int dm9000_isr_is_on(const rtems_irq_connect_data *irq) +{ + return ((rINTMSK & BIT_EINT4_7) == 0)? 1:0; /* any interrupts enabled? */ +} + +/* interrupt handler */ +rtems_isr dm9000_isr (rtems_vector_number v) +{ +#if !defined(CONFIG_NET_POLL_CONTROLLER) + rEINTMASK |= 0x80; +#endif + if ((DM9000_ior(DM9000_ISR) & 0x01)) + { + rtems_event_send (softc.rxDaemonTid, START_RECEIVE_EVENT); + DM9000_iow(DM9000_ISR, 0x01); + } + +#if !defined(CONFIG_NET_POLL_CONTROLLER) + rEINTPEND = 0x80; + ClearPending(BIT_EINT4_7); + rEINTMASK &= ~0x80; +#endif +} + +/* Driver ioctl handler */ +static int +dm9000_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data) +{ + dm9000_softc_t *sc = ifp->if_softc; + int error = 0; + + switch (command) { + case SIOCGIFADDR: + case SIOCSIFADDR: + ether_ioctl (ifp, command, data); + break; + + case SIOCSIFFLAGS: + switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) + { + case IFF_RUNNING: + dm9000_stop (sc); + break; + + case IFF_UP: + dm9000_init (sc); + break; + + case IFF_UP | IFF_RUNNING: + dm9000_stop (sc); + dm9000_init (sc); + break; + + default: + break; + } /* switch (if_flags) */ + break; + + case SIO_RTEMS_SHOW_STATS: + dm9000_stats (sc); + break; + + /* + * FIXME: All sorts of multicast commands need to be added here! + */ + default: + error = EINVAL; + break; + } /* switch (command) */ + return error; +} + +static uint32_t dm9000_outmbuf_8bit(struct mbuf *m) +{ + struct mbuf *l; + uint32_t length = 0; + + l = m; + while (l != NULL) + { + if (l->m_len > 0) + dm9000_outblk_8bit(mtod(l, void *), l->m_len); + + length += l->m_len; /* update offset */ + l = l->m_next; /* get next mbuf, if any */ + } + return (length); +} + + +static uint32_t dm9000_outmbuf_16bit(struct mbuf *m) +{ + uint32_t offset = 0; + uint32_t len; + uint8_t data[2]; + uint8_t *ptr; + uint32_t length = 0; + struct mbuf *l; + + l = m; + while (l != NULL) + { + if (l->m_len > 0) + { + ptr = ((uint8_t *)mtod(l, void *)); + len = l->m_len - offset; + + if (offset == 1) + { + data[1] = *ptr; + dm9000_outblk_16bit(data, 2); + } + + dm9000_outblk_16bit((ptr + offset), (len & 0xFFFFFFFE)); + offset = len & 0x1; + + if (offset) + { + data[0] = *(ptr + l->m_len - 1); + } + } + length += l->m_len; + l = l->m_next; + } + + if (offset) + dm9000_outblk_16bit(data, 1); + + return (length); +} + + +static uint32_t dm9000_outmbuf_32bit(struct mbuf *m) +{ + struct mbuf *l; + uint32_t length = 0; + uint8_t packet[2000]; + + l = m; + while (l != NULL) { + memcpy(((char *)packet + length), /* offset into pkt for mbuf */ + (char *)mtod(l, void *), /* cast to void */ + l->m_len); /* length of this mbuf */ + + length += l->m_len; /* update offset */ + l = l->m_next; /* get next mbuf, if any */ + } + dm9000_outblk_32bit(packet, length); + return (length); +} + +static void dm9000_outblk_8bit(volatile void *data_ptr, int count) +{ + int i; + for (i = 0; i < count; i++) + DM9000_outb((((uint8_t *) data_ptr)[i] & 0xff), DM9000_DATA); +} + +static void dm9000_outblk_16bit(volatile void *data_ptr, int count) +{ + int i; + uint32_t tmplen = (count + 1) / 2; + + for (i = 0; i < tmplen; i++) + DM9000_outw(((uint16_t *) data_ptr)[i], DM9000_DATA); +} +static void dm9000_outblk_32bit(volatile void *data_ptr, int count) +{ + int i; + uint32_t tmplen = (count + 3) / 4; + + for (i = 0; i < tmplen; i++) + DM9000_outl(((uint32_t *) data_ptr)[i], DM9000_DATA); +} + +static void dm9000_inblk_8bit(void *data_ptr, int count) +{ + int i; + for (i = 0; i < count; i++) + ((uint8_t *) data_ptr)[i] = DM9000_inb(DM9000_DATA); +} + +static void dm9000_inblk_16bit(void *data_ptr, int count) +{ + int i; + uint32_t tmplen = (count + 1) / 2; + + for (i = 0; i < tmplen; i++) + ((uint16_t *) data_ptr)[i] = DM9000_inw(DM9000_DATA); +} +static void dm9000_inblk_32bit(void *data_ptr, int count) +{ + int i; + uint32_t tmplen = (count + 3) / 4; + + for (i = 0; i < tmplen; i++) + ((uint32_t *) data_ptr)[i] = DM9000_inl(DM9000_DATA); +} + +static void dm9000_rx_status_32bit(uint16_t *RxStatus, uint16_t *RxLen) +{ + uint32_t tmpdata; + + DM9000_outb(DM9000_MRCMD, DM9000_IO); + + tmpdata = DM9000_inl(DM9000_DATA); + *RxStatus = __le16_to_cpu(tmpdata); + *RxLen = __le16_to_cpu(tmpdata >> 16); +} + +static void dm9000_rx_status_16bit(uint16_t *RxStatus, uint16_t *RxLen) +{ + DM9000_outb(DM9000_MRCMD, DM9000_IO); + + *RxStatus = __le16_to_cpu(DM9000_inw(DM9000_DATA)); + *RxLen = __le16_to_cpu(DM9000_inw(DM9000_DATA)); +} + +static void dm9000_rx_status_8bit(uint16_t *RxStatus, uint16_t *RxLen) +{ + DM9000_outb(DM9000_MRCMD, DM9000_IO); + + *RxStatus = + __le16_to_cpu(DM9000_inb(DM9000_DATA) + + (DM9000_inb(DM9000_DATA) << 8)); + *RxLen = + __le16_to_cpu(DM9000_inb(DM9000_DATA) + + (DM9000_inb(DM9000_DATA) << 8)); +} + +/* + Read a byte from I/O port +*/ +static uint8_t +DM9000_ior(int reg) +{ + DM9000_outb(reg, DM9000_IO); + return DM9000_inb(DM9000_DATA); +} + +/* + Write a byte to I/O port +*/ +static void +DM9000_iow(int reg, uint8_t value) +{ + DM9000_outb(reg, DM9000_IO); + DM9000_outb(value, DM9000_DATA); +} + +/* + Read a word from phyxcer +*/ +static uint16_t +phy_read(int reg) +{ + uint16_t val; + + /* Fill the phyxcer register into REG_0C */ + DM9000_iow(DM9000_EPAR, DM9000_PHY | reg); + DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */ + udelay(100); /* Wait read complete */ + DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */ + val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL); + + /* The read data keeps on REG_0D & REG_0E */ + DM9000_DBG("phy_read(0x%x): 0x%x\n", reg, val); + return val; +} + +/* + Write a word to phyxcer +*/ +static void +phy_write(int reg, uint16_t value) +{ + /* Fill the phyxcer register into REG_0C */ + DM9000_iow(DM9000_EPAR, DM9000_PHY | reg); + + /* Fill the written data into REG_0D & REG_0E */ + DM9000_iow(DM9000_EPDRL, (value & 0xff)); + DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff)); + DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */ + udelay(500); /* Wait write complete */ + DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */ + DM9000_DBG("phy_write(reg:0x%x, value:0x%x)\n", reg, value); +} + +static void udelay(uint32_t us) +{ + uint32_t i, j; + + for (i = 0; i < us; i++) + for (j = 0; j < 1000; j++) + asm volatile("nop"); +} + +#ifdef CONFIG_DM9000_DEBUG +static void +dump_regs(void) +{ + DM9000_DBG("\n"); + DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0)); + DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1)); + DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2)); + DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3)); + DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4)); + DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5)); + DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6)); + DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR)); + DM9000_DBG("\n"); +} +#endif + +/* + Search DM9000 board, allocate space and register it +*/ +int +dm9000_probe(void) +{ + uint32_t id_val; + id_val = DM9000_ior(DM9000_VIDL); + id_val |= DM9000_ior(DM9000_VIDH) << 8; + id_val |= DM9000_ior(DM9000_PIDL) << 16; + id_val |= DM9000_ior(DM9000_PIDH) << 24; + if (id_val == DM9000_ID) { + printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE, + id_val); + return 0; + } else { + printf("dm9000 not found at 0x%08x id: 0x%08x\n", + CONFIG_DM9000_BASE, id_val); + return -1; + } +} + +/* General Purpose dm9000 reset routine */ +static void +dm9000_reset(void) +{ + DM9000_DBG("resetting DM9000\n"); + + /* Reset DM9000, + see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */ + + /* DEBUG: Make all GPIO0 outputs, all others inputs */ + DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT); + /* Step 1: Power internal PHY by writing 0 to GPIO0 pin */ + DM9000_iow(DM9000_GPR, 0); + /* Step 2: Software reset */ + DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); + + do { + DM9000_DBG("resetting the DM9000, 1st reset\n"); + udelay(25); /* Wait at least 20 us */ + } while (DM9000_ior(DM9000_NCR) & 1); + + DM9000_iow(DM9000_NCR, 0); + DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */ + + do { + DM9000_DBG("resetting the DM9000, 2nd reset\n"); + udelay(25); /* Wait at least 20 us */ + } while (DM9000_ior(DM9000_NCR) & 1); + + /* Check whether the ethernet controller is present */ + if ((DM9000_ior(DM9000_PIDL) != 0x0) || + (DM9000_ior(DM9000_PIDH) != 0x90)) + printf("ERROR: resetting DM9000 -> not responding\n"); +} + +/* Initilize dm9000 MAC, without reset +*/ +int dm9000_set_mac(dm9000_softc_t *sc) +{ + int i,oft; + printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", sc->arpcom.ac_enaddr[0], + sc->arpcom.ac_enaddr[1], sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3], + sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5]); + + /* fill device MAC address registers */ + for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) + DM9000_iow(oft, sc->arpcom.ac_enaddr[i]); + for (i = 0, oft = 0x16; i < 8; i++, oft++) + DM9000_iow(oft, 0xff); + + /* read back mac, just to be sure */ + for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) + DM9000_DBG("%02x:", DM9000_ior(oft)); + DM9000_DBG("\n"); + + return 0; +} diff --git a/c/src/lib/libbsp/arm/mini2440/preinstall.am b/c/src/lib/libbsp/arm/mini2440/preinstall.am new file mode 100644 index 0000000..e2bd7e9 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/preinstall.am @@ -0,0 +1,79 @@ +## Automatically generated by ampolish3 - Do not edit + +if AMPOLISH3 +$(srcdir)/preinstall.am: Makefile.am + $(AMPOLISH3) $(srcdir)/Makefile.am > $(srcdir)/preinstall.am +endif + +PREINSTALL_DIRS = +DISTCLEANFILES += $(PREINSTALL_DIRS) + +all-local: $(TMPINSTALL_FILES) + +TMPINSTALL_FILES = +CLEANFILES = $(TMPINSTALL_FILES) + +all-am: $(PREINSTALL_FILES) + +PREINSTALL_FILES = +CLEANFILES += $(PREINSTALL_FILES) + +$(PROJECT_LIB)/$(dirstamp): + @$(MKDIR_P) $(PROJECT_LIB) + @: > $(PROJECT_LIB)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_LIB)/$(dirstamp) + +$(PROJECT_INCLUDE)/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE) + @: > $(PROJECT_INCLUDE)/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp) + +$(PROJECT_INCLUDE)/bsp/$(dirstamp): + @$(MKDIR_P) $(PROJECT_INCLUDE)/bsp + @: > $(PROJECT_INCLUDE)/bsp/$(dirstamp) +PREINSTALL_DIRS += $(PROJECT_INCLUDE)/bsp/$(dirstamp) + +$(PROJECT_LIB)/bsp_specs: bsp_specs $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_LIB)/bsp_specs +PREINSTALL_FILES += $(PROJECT_LIB)/bsp_specs + +$(PROJECT_INCLUDE)/bsp.h: include/bsp.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/bsp.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp.h + +$(PROJECT_INCLUDE)/smc.h: smc/smc.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/smc.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/smc.h + +$(PROJECT_INCLUDE)/tm27.h: ../../shared/include/tm27.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/tm27.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/tm27.h + +$(PROJECT_INCLUDE)/bspopts.h: include/bspopts.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/bspopts.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bspopts.h + +$(PROJECT_INCLUDE)/bsp/bootcard.h: ../../shared/include/bootcard.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/bsp/bootcard.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bootcard.h + +$(PROJECT_INCLUDE)/coverhd.h: ../../shared/include/coverhd.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/coverhd.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/coverhd.h + +$(PROJECT_LIB)/start.$(OBJEXT): start.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_LIB)/start.$(OBJEXT) +TMPINSTALL_FILES += $(PROJECT_LIB)/start.$(OBJEXT) + +$(PROJECT_LIB)/linkcmds: startup/linkcmds $(PROJECT_LIB)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_LIB)/linkcmds +PREINSTALL_FILES += $(PROJECT_LIB)/linkcmds + +$(PROJECT_INCLUDE)/bsp/irq-generic.h: ../../shared/include/irq-generic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/bsp/irq-generic.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-generic.h + +$(PROJECT_INCLUDE)/bsp/irq-info.h: ../../shared/include/irq-info.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/bsp/irq-info.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h + diff --git a/c/src/lib/libbsp/arm/mini2440/smc/smc.c b/c/src/lib/libbsp/arm/mini2440/smc/smc.c new file mode 100644 index 0000000..63485dc --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/smc/smc.c @@ -0,0 +1,652 @@ +/* smc.c -- 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 S3c2440 uses a different register map */ +#ifdef CPU_S3C2440 +#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; +} + + +/* assumes chip enabled + bit 7: write protected = 0, write enabled = 1 + bit 6: busy = 0, ready = 1 + bit 0: success = 0, failed = 1 + + returns 1 on success, 0 on fail +*/ +#if UNUSED +static uint8_t sm_status() +{ + uint8_t status; + + sm_cle_en(); + sm_write_en(); + sm_write(READ_STATUS_CMD); + sm_write_dis(); + sm_cle_dis(); + + sm_read_en(); + status = sm_read(); + sm_read_dis(); + + if (status == 0xC0) + return 1; + else + return 0; +} +#endif + +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.*/ +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; +} + +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(); + +} + +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++; + } + } + } +} + + +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; + } +} + +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(); +} + +/********** + * Function: sm_ECCEncode (completely ripped, unaltered, from the samsung routines) + * Remark: + * - adopted from "ECC Algorithm for SmartMedia V3.0" + * by Memory Product & Technology, Samsung Electronics Co. (ecc30.pdf) + **********/ +int sm_ECCEncode(const uint8_t * p_buf, uint8_t * p_ecc) +{ + uint32_t i, j; + uint8_t paritr[256], tmp = 0, tmp2 = 0; + uint8_t data_table0[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; + uint8_t data_table1[16] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 }; + uint8_t sum = 0, paritc = 0; + uint8_t parit0c = 0, parit1c = 0, parit2c = 0, parit3c = 0; + uint8_t parit4c = 0, parit5c = 0, parit6c = 0, parit7c = 0; + uint8_t parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2; + uint8_t parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 = 0, parit32_1 = 0, parit32_2 = 0; + uint8_t parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 = 0, parit256_1 = 0, parit256_2 = 0; + uint8_t parit512_1 = 0, parit512_2 = 0, parit1024_1 = 0, parit1024_2 = 0; + uint8_t* paritr_ptr; + + paritr_ptr = paritr; + for (i = 0; i < 256; ++i, ++paritr_ptr, ++p_buf) + { + paritc ^= *p_buf; + tmp = (*p_buf & 0xf0) >> 4; + tmp2 = *p_buf & 0x0f; + + switch (tmp) + { + case 0: + case 3: + case 5: + case 6: + case 9: + case 10: + case 12: + case 15: + *paritr_ptr = *(data_table0 + tmp2); + break; + + case 1: + case 2: + case 4: + case 7: + case 8: + case 11: + case 13: + case 14: + *paritr_ptr = *(data_table1 + tmp2); + break; + } + } + + parit0c = (paritc & 0x01) ? 1 : 0; + parit1c = (paritc & 0x02) ? 1 : 0; + parit2c = (paritc & 0x04) ? 1 : 0; + parit3c = (paritc & 0x08) ? 1 : 0; + parit4c = (paritc & 0x10) ? 1 : 0; + parit5c = (paritc & 0x20) ? 1 : 0; + parit6c = (paritc & 0x40) ? 1 : 0; + parit7c = (paritc & 0x80) ? 1 : 0; + parit1_2 = parit6c ^ parit4c ^ parit2c ^ parit0c; + parit1_1 = parit7c ^ parit5c ^ parit3c ^ parit1c; + parit2_2 = parit5c ^ parit4c ^ parit1c ^ parit0c; + parit2_1 = parit7c ^ parit6c ^ parit3c ^ parit2c; + parit4_2 = parit3c ^ parit2c ^ parit1c ^ parit0c; + parit4_1 = parit7c ^ parit6c ^ parit5c ^ parit4c; + + paritr_ptr = paritr; + for (i = 0; i < 256; ++i, ++paritr_ptr) + { + sum ^= *paritr_ptr; + } + + paritr_ptr = paritr; + for (i = 0; i < 256; i += 2, paritr_ptr += 2) + { + parit8_2 ^= *paritr_ptr; + } + + paritr_ptr = paritr; + for (i = 0; i < 256; i += 4, paritr_ptr += 4) + { + parit16_2 ^= *paritr_ptr; + parit16_2 ^= *(paritr_ptr + 1); + } + + paritr_ptr = paritr; + for (i = 0; i < 256; i += 8, paritr_ptr += 8) + { + for (j = 0; j <= 3; ++j) + { + parit32_2 ^= *(paritr_ptr + j); + } + } + + paritr_ptr = paritr; + for (i = 0; i < 256; i += 16, paritr_ptr += 16) + { + for (j = 0; j <= 7; ++j) + { + parit64_2 ^= *(paritr_ptr + j); + } + } + + paritr_ptr = paritr; + for (i = 0; i < 256; i += 32, paritr_ptr += 32) + { + for (j = 0; j <= 15; ++j) + { + parit128_2 ^= *(paritr_ptr + j); + } + } + + paritr_ptr = paritr; + for (i = 0; i < 256; i += 64, paritr_ptr += 64) + { + for (j = 0; j <= 31; ++j) + { + parit256_2 ^= *(paritr_ptr + j); + } + } + + paritr_ptr = paritr; + for (i = 0; i < 256; i += 128, paritr_ptr += 128) + { + for (j = 0; j <= 63; ++j) + { + parit512_2 ^= *(paritr_ptr + j); + } + } + + paritr_ptr = paritr; + for (i = 0; i < 256; i += 256, paritr_ptr += 256) + { + for (j = 0; j <= 127; ++j) + { + parit1024_2 ^= *(paritr_ptr + j); + } + } + + if (sum==0) + { + parit1024_1 = parit1024_2; + parit512_1 = parit512_2; + parit256_1 = parit256_2; + parit128_1 = parit128_2; + parit64_1 = parit64_2; + parit32_1 = parit32_2; + parit16_1 = parit16_2; + parit8_1 = parit8_2; + } + else + { + parit1024_1 = parit1024_2 ? 0 : 1; + parit512_1 = parit512_2 ? 0 : 1; + parit256_1 = parit256_2 ? 0 : 1; + parit128_1 = parit128_2 ? 0 : 1; + parit64_1 = parit64_2 ? 0 : 1; + parit32_1 = parit32_2 ? 0 : 1; + parit16_1 = parit16_2 ? 0 : 1; + parit8_1 = parit8_2 ? 0 : 1; + } + + parit1_2 <<= 2; + parit1_1 <<= 3; + parit2_2 <<= 4; + parit2_1 <<= 5; + parit4_2 <<= 6; + parit4_1 <<= 7; + parit128_1 <<= 1; + parit256_2 <<= 2; + parit256_1 <<= 3; + parit512_2 <<= 4; + parit512_1 <<= 5; + parit1024_2 <<= 6; + parit1024_1 <<= 7; + parit8_1 <<= 1; + parit16_2 <<= 2; + parit16_1 <<= 3; + parit32_2 <<= 4; + parit32_1 <<= 5; + parit64_2 <<= 6; + parit64_1 <<= 7; + + p_ecc[0] = ~(parit64_1 | parit64_2 | parit32_1 | parit32_2 | parit16_1 | parit16_2 | parit8_1 | parit8_2); + p_ecc[1] = ~(parit1024_1 |parit1024_2 | parit512_1 | parit512_2 | parit256_1 | parit256_2 | parit128_1 | parit128_2); + p_ecc[2] = ~(parit4_1 | parit4_2 | parit2_1 | parit2_2 | parit1_1 | parit1_2); + + return 0; +} + +/* smc_write -- + * write stub +*/ +static int smc_write(rtems_blkdev_request *req) +{ + req->req_done(req->done_arg, 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; + } + req->req_done(req->done_arg, 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/mini2440/smc/smc.h b/c/src/lib/libbsp/arm/mini2440/smc/smc.h new file mode 100644 index 0000000..cd886ef --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/smc/smc.h @@ -0,0 +1,28 @@ +#ifndef __SMC_H__ +#define __SMC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems.h> + +#include "rtems/blkdev.h" + +/* 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/mini2440/start/start.S b/c/src/lib/libbsp/arm/mini2440/start/start.S new file mode 100644 index 0000000..f628366 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/start/start.S @@ -0,0 +1,209 @@ +/* + * MINI2440 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.com/license/LICENSE. + * + * + * $Id: start.S,v 1.5 2010/04/07 21:49:51 joel Exp $ + */ + +/* 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 + +@--------------------------------------------------------------------------------- +@ AXF addresses +@--------------------------------------------------------------------------------- + .word _axf_text_start + .word _axf_ro_end + .word _axf_data_start + .word _axf_bss_end + .word _axf_bss_start + .word _axf_bss_end + +@--------------------------------------------------------------------------------- +@ GamePark magic sequence +@--------------------------------------------------------------------------------- + .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 + +@--------------------------------------------------------------------------------- +_start2: +@--------------------------------------------------------------------------------- + + /* + * 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 + + /* zero the bss */ + ldr r1, =_axf_bss_end + ldr r0, =_axf_bss_start + +_bss_init: + mov r2, #0 + cmp r0, r1 + strlot r2, [r0], #4 + blo _bss_init /* loop while r0 < r1 */ + + /* --- 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, =_irq_stack_size + ldr sp, =_irq_stack + 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, =_fiq_stack_size + ldr sp, =_fiq_stack + 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, =_abt_stack_size + ldr sp, =_abt_stack + 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, =_svc_stack_size + ldr sp, =_svc_stack + 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/mini2440/startup/bspreset.c b/c/src/lib/libbsp/arm/mini2440/startup/bspreset.c new file mode 100644 index 0000000..5821d46 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/startup/bspreset.c @@ -0,0 +1,40 @@ +/* + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id: bspreset.c,v 1.2 2009/11/29 14:53:00 ralf Exp $ + */ + +#include <bsp.h> + +void bsp_reset(void) +{ +#if 0 + rtems_interrupt_level level; + rtems_interrupt_disable(level); + /* disable mmu, invalide i-cache and call swi #4 */ + asm volatile("" + "mrc p15,0,r0,c1,c0,0 \n" + "bic r0,r0,#1 \n" + "mcr p15,0,r0,c1,c0,0 \n" + "nop \n" + "nop \n" + "nop \n" + "nop \n" + "nop \n" + "mov r0,#0 \n" + "MCR p15,0,r0,c7,c5,0 \n" + "nop \n" + "nop \n" + "nop \n" + "nop \n" + "nop \n" + "swi #4 " + : + : + : "r0" + ); +#endif + /* we should be back in bios now */ +} diff --git a/c/src/lib/libbsp/arm/mini2440/startup/bspstart.c b/c/src/lib/libbsp/arm/mini2440/startup/bspstart.c new file mode 100644 index 0000000..3f61609 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/startup/bspstart.c @@ -0,0 +1,109 @@ +/*-------------------------------------------------------------------------+ +| 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) 2011 RickLeaf +| Ricky Wu, mailto:[email protected] +| +| The license and distribution terms for this file may be +| found in found in the file LICENSE in this distribution or at +| http://www.rtems.com/license/LICENSE. +| ++--------------------------------------------------------------------------*/ + + +#include <bsp.h> +#include <bsp/irq-generic.h> +#include <rtems/bspIo.h> +#include <s3c24xx.h> + +/* + * External Prototypes + */ +extern void rtems_exception_init_mngt(void); + +/* + * BSP specific Idle task + */ +Thread bsp_idle_task(uint32_t ignored) +{ + while(1) { + asm volatile ("MCR p15,0,r0,c7,c0,4 \n"); + } +} + +/* + * BSP Specific Initialization in C + */ +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; + } + /**/ + rCAMDIVN=0; + + /* setup clocks */ + rCLKDIVN = M_CLKDIVN; + rMPLLCON = ((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV); + /* setup rREFRESH + * period + */ + REFCNT = 1113; + 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 & 0xFFFE01FF; + rTCFG0 = (cr | (16<<8)); + + /* set prescaler for timers 0,1 to 1(0+1) */ + cr = rTCFG0 & 0xFFFFFF00; + rTCFG0 = (cr | (0<<0)); + + /* + * Init rtems exceptions management + */ + rtems_exception_init_mngt(); + + /* + * Init rtems interrupt management + */ + if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) { + _CPU_Fatal_halt(0xe); + } +} + +/* + * 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/mini2440/startup/linkcmds b/c/src/lib/libbsp/arm/mini2440/startup/linkcmds new file mode 100644 index 0000000..9c0617d --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/startup/linkcmds @@ -0,0 +1,279 @@ +/* + * MINI2440 Linker script + * + * Written by Ricky Wu <[email protected]> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * $Id: linkcmds,v 1.4 2008/09/19 21:13:59 joel Exp $ + */ +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm","elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +/* SEARCH_DIR(/usr/local/rtems-arm-dev-tools/arm-rtems/lib); */ + + +MEMORY { + sdram : ORIGIN = 0x30000000, LENGTH = 64M +} + +/* + * Declare some sizes. + */ + +/* The base for SDRAM is set to umon's APPRAMBASE */ +_sdram_base = DEFINED(_sdram_base) ? _sdram_base : 0x30000000; +_sdram_size = DEFINED(_sdram_size) ? _sdram_size : 64M; + +RamBase = _sdram_base; +RamSize = _sdram_size; +HeapSize = DEFINED(HeapSize) ? HeapSize : 0x0; + +_irq_stack_size = DEFINED(_irq_stack_size) ? _irq_stack_size : 0x1000; +_fiq_stack_size = DEFINED(_fiq_stack_size) ? _fiq_stack_size : 0x400; +_abt_stack_size = DEFINED(_abt_stack_size) ? _abt_stack_size : 0x100; +_svc_stack_size = DEFINED(_svc_stack_size) ? _svc_stack_size : 0x1000; + + + +/* Do we need any of these for elf? + __DYNAMIC = 0; */ + +SECTIONS +{ + .base : + { + arm_exception_table = .; + + arm_reset_vect = .; /* 0x00 */ + . += 4; + + arm_undef_vect = .; /* 0x04 */ + . += 4; + + arm_swi_vect = .; /* 0x08 */ + . += 4; + + arm_iabrt_vect = .; /* 0x0c */ + . += 4; + + arm_dabrt_vect = .; /* 0x10 */ + . += 4; + + /* no vector here */ + . += 4; + + arm_irq_vect = .; /* 0x18 */ + . += 4; + + arm_fiq_vect = .; /* 0x1c */ + . += 4; + /* FIXME: */ + + rtems_vector_table = .; + . += (8 * 4); /* 8 ARM interrupts */ + + bsp_vector_table = .; + . += (32 * 4); /* 32 S3C2400 interrupts */ + + . = ALIGN (0x100); + + + } > sdram + + + .text : + { + _axf_text_start = . ; + *(EXCLUDE_FILE (*text.iwram*) .text) + *(.text.*) + *(.stub) + + /* + * Special FreeBSD sysctl sections. + */ + . = ALIGN (16); + __start_set_sysctl_set = .; + *(set_sysctl_*); + __stop_set_sysctl_set = ABSOLUTE(.); + *(set_domain_*); + *(set_pseudo_*); + + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + *(.glue_7) + *(.glue_7t) + + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } > sdram + + __text_end = . ; + + .init : + { + *(.init) + } > sdram /*=0*/ + + .jcr : + { + *(.jcr) + } > sdram + + + .fini : + { + *(.fini) + } > sdram /*=0*/ + + .rodata : + { + *(.rodata) + *all.rodata*(*) + *(.roda) + *(.rodata.*) + *(.gnu.linkonce.r*) + SORT(CONSTRUCTORS) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } > sdram = 0xff + + .ctors : + { + /* gcc uses crtbegin.o to find the start of the constructors, so + we make sure it is first. Because this is a wildcard, it + doesn't matter if the user does not actually link against + crtbegin.o; the linker won't look for a file to match a + wildcard. The wildcard also means that it doesn't matter which + directory crtbegin.o is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >sdram = 0 + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >sdram = 0 + + + .eh_frame : + { + KEEP (*(.eh_frame)) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >sdram = 0 + + .gcc_except_table : + { + *(.gcc_except_table*) + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >sdram = 0 + _axf_ro_end = . ; + + .data ALIGN(4) : + { + _axf_data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d*) + CONSTRUCTORS + . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ + } >sdram = 0xff + + __data_end = . ; + + .bss ALIGN(4): + { + _axf_bss_start = ABSOLUTE(.); + _clear_start = .; + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(64); + _clear_end = .; + + . = ALIGN (256); + _abt_stack = .; + . += _abt_stack_size; + + . = ALIGN (256); + _irq_stack = .; + . += _irq_stack_size; + + . = ALIGN (256); + _fiq_stack = .; + . += _fiq_stack_size; + + . = ALIGN (256); + _svc_stack = .; + . += _svc_stack_size; + +/* + * Ideally, the MMU's translation table would be in SRAM. But we + * don't have any. If we don't use more regions than TLB entries (64), + * the lookup will only happen once for each region. + */ + . = ALIGN (16 * 1024); + _ttbl_base = .; + . += (16 * 1024); + + . = ALIGN (1024); + _bss_free_start = .; + WorkAreaBase = .; + + } > sdram + _axf_bss_end = . ; + + _end = . ; + __end__ = . ; + PROVIDE (end = _end); + + +/* Debugging stuff follows? */ + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /*.stack 0x80000 : { _stack = .; *(.stack) }*/ + /* These must appear regardless of . */ +} + diff --git a/c/src/lib/libbsp/arm/mini2440/startup/memmap.c b/c/src/lib/libbsp/arm/mini2440/startup/memmap.c new file mode 100644 index 0000000..ba1f778 --- /dev/null +++ b/c/src/lib/libbsp/arm/mini2440/startup/memmap.c @@ -0,0 +1,29 @@ +/* + * MINI2440 Memory Map + * + * Copyright (c) 2011 by RickLeaf + * Written by Ricky Wu <[email protected]> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.com/license/LICENSE. + * + * $Id: memmap.c,v 1.2 2007/03/12 11:18:49 joel Exp $ + */ +#include <rtems.h> +#include <libcpu/mmu.h> + +/* Remember, the ARM920 has 64 TLBs. If you have more 1MB sections than + * that, you'll have TLB lookups, which could hurt performance. + */ +mmu_sect_map_t mem_map[] = { +/* <phys addr> <virt addr> <size> <flags> */ + {0x30000000, 0x00000000, 1, MMU_CACHE_NONE}, /* SDRAM for vectors */ + {0x20000000, 0x20000000, 1, MMU_CACHE_NONE}, /* for DM9000 */ + {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 */ +}; diff --git a/c/src/lib/libcpu/arm/Makefile.am b/c/src/lib/libcpu/arm/Makefile.am index d3e7d8f..1d13afd 100644 --- a/c/src/lib/libcpu/arm/Makefile.am +++ b/c/src/lib/libcpu/arm/Makefile.am @@ -137,7 +137,8 @@ mc9328mxl_irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS) endif if s3c24xx -include_HEADERS = s3c24xx/include/s3c24xx.h s3c24xx/include/s3c2400.h s3c24xx/include/s3c2410.h +include_HEADERS = s3c24xx/include/s3c24xx.h s3c24xx/include/s3c2400.h s3c24xx/include/s3c2410.h \ + s3c24xx/include/s3c2440.h ## s3c24xx/clock noinst_PROGRAMS += s3c24xx/clock.rel diff --git a/c/src/lib/libcpu/arm/configure.ac b/c/src/lib/libcpu/arm/configure.ac index df6d179..15774ae 100644 --- a/c/src/lib/libcpu/arm/configure.ac +++ b/c/src/lib/libcpu/arm/configure.ac @@ -23,6 +23,7 @@ RTEMS_PROG_CCAS AM_CONDITIONAL(shared, test "$RTEMS_CPU_MODEL" = "at91rm9200" || \ test "$RTEMS_CPU_MODEL" = "mc9328mxl" || \ + test "$RTEMS_CPU_MODEL" = "s3c2440" || \ test "$RTEMS_CPU_MODEL" = "s3c2410" || \ test "$RTEMS_CPU_MODEL" = "s3c2400" || \ test "$RTEMS_CPU_MODEL" = "pxa255") @@ -32,6 +33,7 @@ AM_CONDITIONAL(mc9328mxl, test "$RTEMS_CPU_MODEL" = "mc9328mxl") AM_CONDITIONAL(lpc22xx, test "$RTEMS_CPU_MODEL" = "lpc22xx") AM_CONDITIONAL(pxa255, test "$RTEMS_CPU_MODEL" = "pxa255") AM_CONDITIONAL(s3c24xx, test "$RTEMS_CPU_MODEL" = "s3c2400" ||\ + test "$RTEMS_CPU_MODEL" = "s3c2440" ||\ test "$RTEMS_CPU_MODEL" = "s3c2410") RTEMS_AMPOLISH3 diff --git a/c/src/lib/libcpu/arm/preinstall.am b/c/src/lib/libcpu/arm/preinstall.am index 751a085..7c32286 100644 --- a/c/src/lib/libcpu/arm/preinstall.am +++ b/c/src/lib/libcpu/arm/preinstall.am @@ -109,6 +109,10 @@ $(PROJECT_INCLUDE)/s3c2410.h: s3c24xx/include/s3c2410.h $(PROJECT_INCLUDE)/$(dir $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/s3c2410.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/s3c2410.h +$(PROJECT_INCLUDE)/s3c2440.h: s3c24xx/include/s3c2440.h $(PROJECT_INCLUDE)/$(dirstamp) + $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/s3c2440.h +PREINSTALL_FILES += $(PROJECT_INCLUDE)/s3c2440.h + $(PROJECT_INCLUDE)/bsp/irq.h: s3c24xx/irq/irq.h $(PROJECT_INCLUDE)/bsp/$(dirstamp) $(INSTALL_DATA) {1}lt; $(PROJECT_INCLUDE)/bsp/irq.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq.h diff --git a/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c b/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c index a801274..8f6282a 100644 --- a/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c +++ b/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c @@ -80,6 +80,26 @@ uint32_t clock_driver_get_nanoseconds_since_last_tick(void) * clock_isr_off(), and clock_isr_is_on() functions can be * NOPs. */ +#ifdef CPU_S3C2440 +#define Clock_driver_support_initialize_hardware() \ + do { \ + uint32_t cr; \ + uint32_t freq; \ + /* set MUX for Timer4 to 1/2 */ \ + cr=rTCFG1 & (~(0xf<<16)); \ + rTCFG1=(cr | (0<<16)); \ + freq = get_PCLK(); \ + /* set TIMER4 counter, input freq=PLCK/16/16Mhz*/ \ + freq = (freq /16); \ + rTCNTB4 = ((freq / 1000) * rtems_configuration_get_microseconds_per_tick()) / 1000; \ + /*unmask TIMER4 irq*/ \ + rINTMSK&=~BIT_TIMER4; \ + /* start TIMER4 with autoreload */ \ + cr=rTCON & 0xFF8FFFFF; \ + rTCON=(cr|(0x6<<20)); \ + rTCON=(cr|(0x5<<20)); \ + } while (0) +#else #define Clock_driver_support_initialize_hardware() \ do { \ uint32_t cr; \ @@ -98,6 +118,7 @@ uint32_t clock_driver_get_nanoseconds_since_last_tick(void) rTCON=(cr|(0x6<<20)); \ rTCON=(cr|(0x5<<20)); \ } while (0) +#endif /** * Do whatever you need to shut the clock down and remove the diff --git a/c/src/lib/libcpu/arm/s3c24xx/include/s3c2440.h b/c/src/lib/libcpu/arm/s3c24xx/include/s3c2440.h new file mode 100644 index 0000000..8154e9e --- /dev/null +++ b/c/src/lib/libcpu/arm/s3c24xx/include/s3c2440.h @@ -0,0 +1,825 @@ +/************************************************ + * NAME : s3c2440.h + * Version : 3.7.2002 + * + * Based on 24x.h for the Samsung Development Board + ************************************************/ + +#ifndef S3C2440_H_ +#define S3C2440_H_ + +/* to be used in assembly code */ +#define rINTOFFSET_ADDR 0x4A000014 +/* Memory control */ +#define rBWSCON (*(volatile unsigned *)0x48000000) +#define rBANKCON0 (*(volatile unsigned *)0x48000004) +#define rBANKCON1 (*(volatile unsigned *)0x48000008) +#define rBANKCON2 (*(volatile unsigned *)0x4800000C) +#define rBANKCON3 (*(volatile unsigned *)0x48000010) +#define rBANKCON4 (*(volatile unsigned *)0x48000014) +#define rBANKCON5 (*(volatile unsigned *)0x48000018) +#define rBANKCON6 (*(volatile unsigned *)0x4800001C) +#define rBANKCON7 (*(volatile unsigned *)0x48000020) +#define rREFRESH (*(volatile unsigned *)0x48000024) +#define rBANKSIZE (*(volatile unsigned *)0x48000028) +#define rMRSRB6 (*(volatile unsigned *)0x4800002C) +#define rMRSRB7 (*(volatile unsigned *)0x48000030) + +/* USB Host Controller */ +#define rHcRevision (*(volatile unsigned *)0x49000000) +#define rHcControl (*(volatile unsigned *)0x49000004) +#define rHcCommonStatus (*(volatile unsigned *)0x49000008) +#define rHcInterruptStatus (*(volatile unsigned *)0x4900000C) +#define rHcInterruptEnable (*(volatile unsigned *)0x49000010) +#define rHcInterruptDisable (*(volatile unsigned *)0x49000014) +#define rHcHCCA (*(volatile unsigned *)0x49000018) +#define rHcPeriodCuttendED (*(volatile unsigned *)0x4900001C) +#define rHcControlHeadED (*(volatile unsigned *)0x49000020) +#define rHcControlCurrentED (*(volatile unsigned *)0x49000024) +#define rHcBulkHeadED (*(volatile unsigned *)0x49000028) +#define rHcBuldCurrentED (*(volatile unsigned *)0x4900002C) +#define rHcDoneHead (*(volatile unsigned *)0x49000030) +#define rHcRmInterval (*(volatile unsigned *)0x49000034) +#define rHcFmRemaining (*(volatile unsigned *)0x49000038) +#define rHcFmNumber (*(volatile unsigned *)0x4900003C) +#define rHcPeriodicStart (*(volatile unsigned *)0x49000040) +#define rHcLSThreshold (*(volatile unsigned *)0x49000044) +#define rHcRhDescriptorA (*(volatile unsigned *)0x49000048) +#define rHcRhDescriptorB (*(volatile unsigned *)0x4900004C) +#define rHcRhStatus (*(volatile unsigned *)0x49000050) +#define rHcRhPortStatus1 (*(volatile unsigned *)0x49000054) +#define rHcRhPortStatus2 (*(volatile unsigned *)0x49000058) + +/* INTERRUPT */ +#define rSRCPND (*(volatile unsigned *)0x4A000000) +#define rINTMOD (*(volatile unsigned *)0x4A000004) +#define rINTMSK (*(volatile unsigned *)0x4A000008) +#define rPRIORITY (*(volatile unsigned *)0x4A00000C) +#define rINTPND (*(volatile unsigned *)0x4A000010) +#define rINTOFFSET (*(volatile unsigned *)0x4A000014) +#define rSUBSRCPND (*(volatile unsigned *)0x4A000018) +#define rINTSUBMSK (*(volatile unsigned *)0x4A00001c) + + +/* DMA */ +#define rDISRC0 (*(volatile unsigned *)0x4B000000) +#define rDISRCC0 (*(volatile unsigned *)0x4B000004) +#define rDIDST0 (*(volatile unsigned *)0x4B000008) +#define rDIDSTC0 (*(volatile unsigned *)0x4B00000C) +#define rDCON0 (*(volatile unsigned *)0x4B000010) +#define rDSTAT0 (*(volatile unsigned *)0x4B000014) +#define rDCSRC0 (*(volatile unsigned *)0x4B000018) +#define rDCDST0 (*(volatile unsigned *)0x4B00001C) +#define rDMASKTRIG0 (*(volatile unsigned *)0x4B000020) +#define rDISRC1 (*(volatile unsigned *)0x4B000040) +#define rDISRCC1 (*(volatile unsigned *)0x4B000044) +#define rDIDST1 (*(volatile unsigned *)0x4B000048) +#define rDIDSTC1 (*(volatile unsigned *)0x4B00004C) +#define rDCON1 (*(volatile unsigned *)0x4B000050) +#define rDSTAT1 (*(volatile unsigned *)0x4B000054) +#define rDCSRC1 (*(volatile unsigned *)0x4B000058) +#define rDCDST1 (*(volatile unsigned *)0x4B00005C) +#define rDMASKTRIG1 (*(volatile unsigned *)0x4B000060) +#define rDISRC2 (*(volatile unsigned *)0x4B000080) +#define rDISRCC2 (*(volatile unsigned *)0x4B000084) +#define rDIDST2 (*(volatile unsigned *)0x4B000088) +#define rDIDSTC2 (*(volatile unsigned *)0x4B00008C) +#define rDCON2 (*(volatile unsigned *)0x4B000090) +#define rDSTAT2 (*(volatile unsigned *)0x4B000094) +#define rDCSRC2 (*(volatile unsigned *)0x4B000098) +#define rDCDST2 (*(volatile unsigned *)0x4B00009C) +#define rDMASKTRIG2 (*(volatile unsigned *)0x4B0000A0) +#define rDISRC3 (*(volatile unsigned *)0x4B0000C0) +#define rDISRCC3 (*(volatile unsigned *)0x4B0000C4) +#define rDIDST3 (*(volatile unsigned *)0x4B0000C8) +#define rDIDSTC3 (*(volatile unsigned *)0x4B0000CC) +#define rDCON3 (*(volatile unsigned *)0x4B0000D0) +#define rDSTAT3 (*(volatile unsigned *)0x4B0000D4) +#define rDCSRC3 (*(volatile unsigned *)0x4B0000D8) +#define rDCDST3 (*(volatile unsigned *)0x4B0000DC) +#define rDMASKTRIG3 (*(volatile unsigned *)0x4B0000E0) + + +/* CLOCK & POWER MANAGEMENT */ +#define rLOCKTIME (*(volatile unsigned *)0x4C000000) +#define rMPLLCON (*(volatile unsigned *)0x4C000004) +#define rUPLLCON (*(volatile unsigned *)0x4C000008) +#define rCLKCON (*(volatile unsigned *)0x4C00000C) +#define rCLKSLOW (*(volatile unsigned *)0x4C000010) +#define rCLKDIVN (*(volatile unsigned *)0x4C000014) +#define rCAMDIVN (*(volatile unsigned *)0x4C000018) + +/* LCD CONTROLLER */ +#define rLCDCON1 (*(volatile unsigned *)0x4D000000) +#define rLCDCON2 (*(volatile unsigned *)0x4D000004) +#define rLCDCON3 (*(volatile unsigned *)0x4D000008) +#define rLCDCON4 (*(volatile unsigned *)0x4D00000C) +#define rLCDCON5 (*(volatile unsigned *)0x4D000010) +#define rLCDSADDR1 (*(volatile unsigned *)0x4D000014) +#define rLCDSADDR2 (*(volatile unsigned *)0x4D000018) +#define rLCDSADDR3 (*(volatile unsigned *)0x4D00001C) +#define rREDLUT (*(volatile unsigned *)0x4D000020) +#define rGREENLUT (*(volatile unsigned *)0x4D000024) +#define rBLUELUT (*(volatile unsigned *)0x4D000028) +#define rREDLUT (*(volatile unsigned *)0x4D000020) +#define rGREENLUT (*(volatile unsigned *)0x4D000024) +#define rBLUELUT (*(volatile unsigned *)0x4D000028) +#define rDITHMODE (*(volatile unsigned *)0x4D00004C) +#define rTPAL (*(volatile unsigned *)0x4D000050) +#define rLCDINTPND (*(volatile unsigned *)0x4D000054) +#define rLCDSRCPND (*(volatile unsigned *)0x4D000058) +#define rLCDINTMSK (*(volatile unsigned *)0x4D00005C) +#define rTCONSEL (*(volatile unsigned *)0x4D000060) +#define PALETTE 0x4d000400 + +/* NAND Flash */ +#define rNFCONF (*(volatile unsigned *)0x4E000000) +#define rNFCMD (*(volatile unsigned *)0x4E000004) +#define rNFADDR (*(volatile unsigned *)0x4E000008) +#define rNFDATA (*(volatile unsigned *)0x4E00000C) +#define rNFSTAT (*(volatile unsigned *)0x4E000010) +#define rNFECC (*(volatile unsigned *)0x4E000014) + +/* UART */ +#define rULCON0 (*(volatile unsigned char *)0x50000000) +#define rUCON0 (*(volatile unsigned short *)0x50000004) +#define rUFCON0 (*(volatile unsigned char *)0x50000008) +#define rUMCON0 (*(volatile unsigned char *)0x5000000C) +#define rUTRSTAT0 (*(volatile unsigned char *)0x50000010) +#define rUERSTAT0 (*(volatile unsigned char *)0x50000014) +#define rUFSTAT0 (*(volatile unsigned short *)0x50000018) +#define rUMSTAT0 (*(volatile unsigned char *)0x5000001C) +#define rUBRDIV0 (*(volatile unsigned short *)0x50000028) + +#define rULCON1 (*(volatile unsigned char *)0x50004000) +#define rUCON1 (*(volatile unsigned short *)0x50004004) +#define rUFCON1 (*(volatile unsigned char *)0x50004008) +#define rUMCON1 (*(volatile unsigned char *)0x5000400C) +#define rUTRSTAT1 (*(volatile unsigned char *)0x50004010) +#define rUERSTAT1 (*(volatile unsigned char *)0x50004014) +#define rUFSTAT1 (*(volatile unsigned short *)0x50004018) +#define rUMSTAT1 (*(volatile unsigned char *)0x5000401C) +#define rUBRDIV1 (*(volatile unsigned short *)0x50004028) + +#define rULCON2 (*(volatile unsigned char *)0x50008000) +#define rUCON2 (*(volatile unsigned short *)0x50008004) +#define rUFCON2 (*(volatile unsigned char *)0x50008008) +#define rUTRSTAT2 (*(volatile unsigned char *)0x50008010) +#define rUERSTAT2 (*(volatile unsigned char *)0x50008014) +#define rUFSTAT2 (*(volatile unsigned short *)0x50008018) +#define rUBRDIV2 (*(volatile unsigned short *)0x50008028) + +#ifdef __BIG_ENDIAN +#define rUTXH0 (*(volatile unsigned char *)0x50000023) +#define rURXH0 (*(volatile unsigned char *)0x50000027) +#define rUTXH1 (*(volatile unsigned char *)0x50004023) +#define rURXH1 (*(volatile unsigned char *)0x50004027) +#define rUTXH2 (*(volatile unsigned char *)0x50008023) +#define rURXH2 (*(volatile unsigned char *)0x50008027) + +#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000023)=(unsigned char)(ch) +#define RdURXH0() (*(volatile unsigned char *)0x50000027) +#define WrUTXH1(ch) (*(volatile unsigned char *)0x50004023)=(unsigned char)(ch) +#define RdURXH1() (*(volatile unsigned char *)0x50004027) +#define WrUTXH2(ch) (*(volatile unsigned char *)0x50008023)=(unsigned char)(ch) +#define RdURXH2() (*(volatile unsigned char *)0x50008027) + +#define UTXH0 (0x50000020+3) /* byte_access address by DMA */ +#define URXH0 (0x50000024+3) +#define UTXH1 (0x50004020+3) +#define URXH1 (0x50004024+3) +#define UTXH2 (0x50008020+3) +#define URXH2 (0x50008024+3) + +#else /* Little Endian */ +#define rUTXH0 (*(volatile unsigned char *)0x50000020) +#define rURXH0 (*(volatile unsigned char *)0x50000024) +#define rUTXH1 (*(volatile unsigned char *)0x50004020) +#define rURXH1 (*(volatile unsigned char *)0x50004024) +#define rUTXH2 (*(volatile unsigned char *)0x50008020) +#define rURXH2 (*(volatile unsigned char *)0x50008024) + +#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch) +#define RdURXH0() (*(volatile unsigned char *)0x50000024) +#define WrUTXH1(ch) (*(volatile unsigned char *)0x50004020)=(unsigned char)(ch) +#define RdURXH1() (*(volatile unsigned char *)0x50004024) +#define WrUTXH2(ch) (*(volatile unsigned char *)0x50008020)=(unsigned char)(ch) +#define RdURXH2() (*(volatile unsigned char *)0x50008024) + +#define UTXH0 (0x50000020) +#define URXH0 (0x50000024) +#define UTXH1 (0x50004020) +#define URXH1 (0x50004024) +#define UTXH2 (0x50008020) +#define URXH2 (0x50008024) +#endif + + +/* PWM TIMER */ +#define rTCFG0 (*(volatile unsigned *)0x51000000) +#define rTCFG1 (*(volatile unsigned *)0x51000004) +#define rTCON (*(volatile unsigned *)0x51000008) +#define rTCNTB0 (*(volatile unsigned *)0x5100000C) +#define rTCMPB0 (*(volatile unsigned *)0x51000010) +#define rTCNTO0 (*(volatile unsigned *)0x51000014) +#define rTCNTB1 (*(volatile unsigned *)0x51000018) +#define rTCMPB1 (*(volatile unsigned *)0x5100001C) +#define rTCNTO1 (*(volatile unsigned *)0x51000020) +#define rTCNTB2 (*(volatile unsigned *)0x51000024) +#define rTCMPB2 (*(volatile unsigned *)0x51000028) +#define rTCNTO2 (*(volatile unsigned *)0x5100002C) +#define rTCNTB3 (*(volatile unsigned *)0x51000030) +#define rTCMPB3 (*(volatile unsigned *)0x51000034) +#define rTCNTO3 (*(volatile unsigned *)0x51000038) +#define rTCNTB4 (*(volatile unsigned *)0x5100003C) +#define rTCNTO4 (*(volatile unsigned *)0x51000040) + + +/* USB DEVICE */ +#ifdef __BIG_ENDIAN +#define rFUNC_ADDR_REG (*(volatile unsigned char *)0x52000143) +#define rPWR_REG (*(volatile unsigned char *)0x52000147) +#define rEP_INT_REG (*(volatile unsigned char *)0x5200014b) +#define rUSB_INT_REG (*(volatile unsigned char *)0x5200015b) +#define rEP_INT_EN_REG (*(volatile unsigned char *)0x5200015f) +#define rUSB_INT_EN_REG (*(volatile unsigned char *)0x5200016f) +#define rFRAME_NUM1_REG (*(volatile unsigned char *)0x52000173) +#define rFRAME_NUM2_REG (*(volatile unsigned char *)0x52000177) +#define rINDEX_REG (*(volatile unsigned char *)0x5200017b) +#define rMAXP_REG (*(volatile unsigned char *)0x52000183) +#define rEP0_CSR (*(volatile unsigned char *)0x52000187) +#define rIN_CSR1_REG (*(volatile unsigned char *)0x52000187) +#define rIN_CSR2_REG (*(volatile unsigned char *)0x5200018b) +#define rOUT_CSR1_REG (*(volatile unsigned char *)0x52000193) +#define rOUT_CSR2_REG (*(volatile unsigned char *)0x52000197) +#define rOUT_FIFO_CNT1_REG (*(volatile unsigned char *)0x5200019b) +#define rOUT_FIFO_CNT2_REG (*(volatile unsigned char *)0x5200019f) +#define rEP0_FIFO (*(volatile unsigned char *)0x520001c3) +#define rEP1_FIFO (*(volatile unsigned char *)0x520001c7) +#define rEP2_FIFO (*(volatile unsigned char *)0x520001cb) +#define rEP3_FIFO (*(volatile unsigned char *)0x520001cf) +#define rEP4_FIFO (*(volatile unsigned char *)0x520001d3) +#define rEP1_DMA_CON (*(volatile unsigned char *)0x52000203) +#define rEP1_DMA_UNIT (*(volatile unsigned char *)0x52000207) +#define rEP1_DMA_FIFO (*(volatile unsigned char *)0x5200020b) +#define rEP1_DMA_TTC_L (*(volatile unsigned char *)0x5200020f) +#define rEP1_DMA_TTC_M (*(volatile unsigned char *)0x52000213) +#define rEP1_DMA_TTC_H (*(volatile unsigned char *)0x52000217) +#define rEP2_DMA_CON (*(volatile unsigned char *)0x5200021b) +#define rEP2_DMA_UNIT (*(volatile unsigned char *)0x5200021f) +#define rEP2_DMA_FIFO (*(volatile unsigned char *)0x52000223) +#define rEP2_DMA_TTC_L (*(volatile unsigned char *)0x52000227) +#define rEP2_DMA_TTC_M (*(volatile unsigned char *)0x5200022b) +#define rEP2_DMA_TTC_H (*(volatile unsigned char *)0x5200022f) +#define rEP3_DMA_CON (*(volatile unsigned char *)0x52000243) +#define rEP3_DMA_UNIT (*(volatile unsigned char *)0x52000247) +#define rEP3_DMA_FIFO (*(volatile unsigned char *)0x5200024b) +#define rEP3_DMA_TTC_L (*(volatile unsigned char *)0x5200024f) +#define rEP3_DMA_TTC_M (*(volatile unsigned char *)0x52000253) +#define rEP3_DMA_TTC_H (*(volatile unsigned char *)0x52000257) +#define rEP4_DMA_CON (*(volatile unsigned char *)0x5200025b) +#define rEP4_DMA_UNIT (*(volatile unsigned char *)0x5200025f) +#define rEP4_DMA_FIFO (*(volatile unsigned char *)0x52000263) +#define rEP4_DMA_TTC_L (*(volatile unsigned char *)0x52000267) +#define rEP4_DMA_TTC_M (*(volatile unsigned char *)0x5200026b) +#define rEP4_DMA_TTC_H (*(volatile unsigned char *)0x5200026f) + +#else /* Little Endian*/ +#define rFUNC_ADDR_REG (*(volatile unsigned char *)0x52000140) +#define rPWR_REG (*(volatile unsigned char *)0x52000144) +#define rEP_INT_REG (*(volatile unsigned char *)0x52000148) +#define rUSB_INT_REG (*(volatile unsigned char *)0x52000158) +#define rEP_INT_EN_REG (*(volatile unsigned char *)0x5200015c) +#define rUSB_INT_EN_REG (*(volatile unsigned char *)0x5200016c) +#define rFRAME_NUM1_REG (*(volatile unsigned char *)0x52000170) +#define rFRAME_NUM2_REG (*(volatile unsigned char *)0x52000174) +#define rINDEX_REG (*(volatile unsigned char *)0x52000178) +#define rMAXP_REG (*(volatile unsigned char *)0x52000180) +#define rEP0_CSR (*(volatile unsigned char *)0x52000184) +#define rIN_CSR1_REG (*(volatile unsigned char *)0x52000184) +#define rIN_CSR2_REG (*(volatile unsigned char *)0x52000188) +#define rOUT_CSR1_REG (*(volatile unsigned char *)0x52000190) +#define rOUT_CSR2_REG (*(volatile unsigned char *)0x52000194) +#define rOUT_FIFO_CNT1_REG (*(volatile unsigned char *)0x52000198) +#define rOUT_FIFO_CNT2_REG (*(volatile unsigned char *)0x5200019c) +#define rEP0_FIFO (*(volatile unsigned char *)0x520001c0) +#define rEP1_FIFO (*(volatile unsigned char *)0x520001c4) +#define rEP2_FIFO (*(volatile unsigned char *)0x520001c8) +#define rEP3_FIFO (*(volatile unsigned char *)0x520001cc) +#define rEP4_FIFO (*(volatile unsigned char *)0x520001d0) +#define rEP1_DMA_CON (*(volatile unsigned char *)0x52000200) +#define rEP1_DMA_UNIT (*(volatile unsigned char *)0x52000204) +#define rEP1_DMA_FIFO (*(volatile unsigned char *)0x52000208) +#define rEP1_DMA_TTC_L (*(volatile unsigned char *)0x5200020c) +#define rEP1_DMA_TTC_M (*(volatile unsigned char *)0x52000210) +#define rEP1_DMA_TTC_H (*(volatile unsigned char *)0x52000214) +#define rEP2_DMA_CON (*(volatile unsigned char *)0x52000218) +#define rEP2_DMA_UNIT (*(volatile unsigned char *)0x5200021c) +#define rEP2_DMA_FIFO (*(volatile unsigned char *)0x52000220) +#define rEP2_DMA_TTC_L (*(volatile unsigned char *)0x52000224) +#define rEP2_DMA_TTC_M (*(volatile unsigned char *)0x52000228) +#define rEP2_DMA_TTC_H (*(volatile unsigned char *)0x5200022c) +#define rEP3_DMA_CON (*(volatile unsigned char *)0x52000240) +#define rEP3_DMA_UNIT (*(volatile unsigned char *)0x52000244) +#define rEP3_DMA_FIFO (*(volatile unsigned char *)0x52000248) +#define rEP3_DMA_TTC_L (*(volatile unsigned char *)0x5200024c) +#define rEP3_DMA_TTC_M (*(volatile unsigned char *)0x52000250) +#define rEP3_DMA_TTC_H (*(volatile unsigned char *)0x52000254) +#define rEP4_DMA_CON (*(volatile unsigned char *)0x52000258) +#define rEP4_DMA_UNIT (*(volatile unsigned char *)0x5200025c) +#define rEP4_DMA_FIFO (*(volatile unsigned char *)0x52000260) +#define rEP4_DMA_TTC_L (*(volatile unsigned char *)0x52000264) +#define rEP4_DMA_TTC_M (*(volatile unsigned char *)0x52000268) +#define rEP4_DMA_TTC_H (*(volatile unsigned char *)0x5200026c) +#endif /* __BIG_ENDIAN */ + +/* WATCH DOG TIMER */ +#define rWTCON (*(volatile unsigned *)0x53000000) +#define rWTDAT (*(volatile unsigned *)0x53000004) +#define rWTCNT (*(volatile unsigned *)0x53000008) + + +/* IIC */ +#define rIICCON (*(volatile unsigned *)0x54000000) +#define rIICSTAT (*(volatile unsigned *)0x54000004) +#define rIICADD (*(volatile unsigned *)0x54000008) +#define rIICDS (*(volatile unsigned *)0x5400000C) + + +/* IIS */ +#define rIISCON (*(volatile unsigned *)0x55000000) +#define rIISMOD (*(volatile unsigned *)0x55000004) +#define rIISPSR (*(volatile unsigned *)0x55000008) +#define rIISFIFCON (*(volatile unsigned *)0x5500000C) + +#ifdef __BIG_ENDIAN +#define IISFIFO ((volatile unsigned short *)0x55000012) + +#else /* Little Endian */ +#define IISFIFO ((volatile unsigned short *)0x55000010) +#endif + + +/* I/O PORT */ +#define rGPACON (*(volatile unsigned *)0x56000000) +#define rGPADAT (*(volatile unsigned *)0x56000004) + +#define rGPBCON (*(volatile unsigned *)0x56000010) +#define rGPBDAT (*(volatile unsigned *)0x56000014) +#define rGPBUP (*(volatile unsigned *)0x56000018) + +#define rGPCCON (*(volatile unsigned *)0x56000020) +#define rGPCDAT (*(volatile unsigned *)0x56000024) +#define rGPCUP (*(volatile unsigned *)0x56000028) + +#define rGPDCON (*(volatile unsigned *)0x56000030) +#define rGPDDAT (*(volatile unsigned *)0x56000034) +#define rGPDUP (*(volatile unsigned *)0x56000038) + +#define rGPECON (*(volatile unsigned *)0x56000040) +#define rGPEDAT (*(volatile unsigned *)0x56000044) +#define rGPEUP (*(volatile unsigned *)0x56000048) + +#define rGPFCON (*(volatile unsigned *)0x56000050) +#define rGPFDAT (*(volatile unsigned *)0x56000054) +#define rGPFUP (*(volatile unsigned *)0x56000058) + +#define rGPGCON (*(volatile unsigned *)0x56000060) +#define rGPGDAT (*(volatile unsigned *)0x56000064) +#define rGPGUP (*(volatile unsigned *)0x56000068) + +#define rGPHCON (*(volatile unsigned *)0x56000070) +#define rGPHDAT (*(volatile unsigned *)0x56000074) +#define rGPHUP (*(volatile unsigned *)0x56000078) + +#define rMISCCR (*(volatile unsigned *)0x56000080) +#define rDCLKCON (*(volatile unsigned *)0x56000084) +#define rEXTINT0 (*(volatile unsigned *)0x56000088) +#define rEXTINT1 (*(volatile unsigned *)0x5600008c) +#define rEXTINT2 (*(volatile unsigned *)0x56000090) +#define rEINTFLT0 (*(volatile unsigned *)0x56000094) +#define rEINTFLT1 (*(volatile unsigned *)0x56000098) +#define rEINTFLT2 (*(volatile unsigned *)0x5600009c) +#define rEINTFLT3 (*(volatile unsigned *)0x560000a0) +#define rEINTMASK (*(volatile unsigned *)0x560000a4) +#define rEINTPEND (*(volatile unsigned *)0x560000a8) +#define rGSTATUS0 (*(volatile unsigned *)0x560000ac) +#define rGSTATUS1 (*(volatile unsigned *)0x560000b0) + +/* RTC */ +#ifdef __BIG_ENDIAN +#define rRTCCON (*(volatile unsigned char *)0x57000043) +#define rTICNT (*(volatile unsigned char *)0x57000047) +#define rRTCALM (*(volatile unsigned char *)0x57000053) +#define rALMSEC (*(volatile unsigned char *)0x57000057) +#define rALMMIN (*(volatile unsigned char *)0x5700005b) +#define rALMHOUR (*(volatile unsigned char *)0x5700005f) +#define rALMDATE (*(volatile unsigned char *)0x57000063) +#define rALMMON (*(volatile unsigned char *)0x57000067) +#define rALMYEAR (*(volatile unsigned char *)0x5700006b) +#define rRTCRST (*(volatile unsigned char *)0x5700006f) +#define rBCDSEC (*(volatile unsigned char *)0x57000073) +#define rBCDMIN (*(volatile unsigned char *)0x57000077) +#define rBCDHOUR (*(volatile unsigned char *)0x5700007b) +#define rBCDDATE (*(volatile unsigned char *)0x5700007f) +#define rBCDDAY (*(volatile unsigned char *)0x57000083) +#define rBCDMON (*(volatile unsigned char *)0x57000087) +#define rBCDYEAR (*(volatile unsigned char *)0x5700008b) + +#else /*Little Endian*/ +#define rRTCCON (*(volatile unsigned char *)0x57000040) +#define rTICNT (*(volatile unsigned char *)0x57000044) +#define rRTCALM (*(volatile unsigned char *)0x57000050) +#define rALMSEC (*(volatile unsigned char *)0x57000054) +#define rALMMIN (*(volatile unsigned char *)0x57000058) +#define rALMHOUR (*(volatile unsigned char *)0x5700005c) +#define rALMDATE (*(volatile unsigned char *)0x57000060) +#define rALMMON (*(volatile unsigned char *)0x57000064) +#define rALMYEAR (*(volatile unsigned char *)0x57000068) +#define rRTCRST (*(volatile unsigned char *)0x5700006c) +#define rBCDSEC (*(volatile unsigned char *)0x57000070) +#define rBCDMIN (*(volatile unsigned char *)0x57000074) +#define rBCDHOUR (*(volatile unsigned char *)0x57000078) +#define rBCDDATE (*(volatile unsigned char *)0x5700007c) +#define rBCDDAY (*(volatile unsigned char *)0x57000080) +#define rBCDMON (*(volatile unsigned char *)0x57000084) +#define rBCDYEAR (*(volatile unsigned char *)0x57000088) +#endif /*RTC*/ + + +/* ADC */ +#define rADCCON (*(volatile unsigned *)0x58000000) +#define rADCTSC (*(volatile unsigned *)0x58000004) +#define rADCDLY (*(volatile unsigned *)0x58000008) +#define rADCDAT0 (*(volatile unsigned *)0x5800000c) +#define rADCDAT1 (*(volatile unsigned *)0x58000010) + + +/* SPI */ +#define rSPCON0 (*(volatile unsigned *)0x59000000) +#define rSPSTA0 (*(volatile unsigned *)0x59000004) +#define rSPPIN0 (*(volatile unsigned *)0x59000008) +#define rSPPRE0 (*(volatile unsigned *)0x5900000c) +#define rSPTDAT0 (*(volatile unsigned *)0x59000010) +#define rSPRDAT0 (*(volatile unsigned *)0x59000014) + +#define rSPCON1 (*(volatile unsigned *)0x59000020) +#define rSPSTA1 (*(volatile unsigned *)0x59000024) +#define rSPPIN1 (*(volatile unsigned *)0x59000028) +#define rSPPRE1 (*(volatile unsigned *)0x5900002c) +#define rSPTDAT1 (*(volatile unsigned *)0x59000030) +#define rSPRDAT1 (*(volatile unsigned *)0x59000034) + +/* SD interface */ +#define rSDICON (*(volatile unsigned *)0x5a000000) +#define rSDIPRE (*(volatile unsigned *)0x5a000004) +#define rSDICARG (*(volatile unsigned *)0x5a000008) +#define rSDICCON (*(volatile unsigned *)0x5a00000c) +#define rSDICSTA (*(volatile unsigned *)0x5a000010) +#define rSDIRSP0 (*(volatile unsigned *)0x5a000014) +#define rSDIRSP1 (*(volatile unsigned *)0x5a000018) +#define rSDIRSP2 (*(volatile unsigned *)0x5a00001c) +#define rSDIRSP3 (*(volatile unsigned *)0x5a000020) +#define rSDIDTIMER (*(volatile unsigned *)0x5a000024) +#define rSDIBSIZE (*(volatile unsigned *)0x5a000028) +#define rSDIDATCON (*(volatile unsigned *)0x5a00002c) +#define rSDIDATCNT (*(volatile unsigned *)0x5a000030) +#define rSDIDATSTA (*(volatile unsigned *)0x5a000034) +#define rSDIFSTA (*(volatile unsigned *)0x5a000038) +#define rSDIIMSK (*(volatile unsigned *)0x5a000040) + +#ifdef __BIG_ENDIAN +#define rSDIDAT (*(volatile unsigned *)0x5a00003F) +#define SDIDAT 0x5a00003F +#else /* Little Endian */ +#define rSDIDAT (*(volatile unsigned *)0x5a00003C) +#define SDIDAT 0x5a00003C +#endif /*SD Interface*/ + + +#define _ISR_STARTADDRESS rtems_vector_table +/* ISR */ +#define pISR_RESET (*(unsigned *)(_ISR_STARTADDRESS+0x0)) +#define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0x4)) +#define pISR_SWI (*(unsigned *)(_ISR_STARTADDRESS+0x8)) +#define pISR_PABORT (*(unsigned *)(_ISR_STARTADDRESS+0xC)) +#define pISR_DABORT (*(unsigned *)(_ISR_STARTADDRESS+0x10)) +#define pISR_RESERVED (*(unsigned *)(_ISR_STARTADDRESS+0x14)) +#define pISR_IRQ (*(unsigned *)(_ISR_STARTADDRESS+0x18)) +#define pISR_FIQ (*(unsigned *)(_ISR_STARTADDRESS+0x1C)) + +#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20)) +#define pISR_EINT1 (*(unsigned *)(_ISR_STARTADDRESS+0x24)) +#define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x28)) +#define pISR_EINT3 (*(unsigned *)(_ISR_STARTADDRESS+0x2C)) +#define pISR_EINT4_7 (*(unsigned *)(_ISR_STARTADDRESS+0x30)) +#define pISR_EINT8_23 (*(unsigned *)(_ISR_STARTADDRESS+0x34)) +#define pISR_BAT_FLT (*(unsigned *)(_ISR_STARTADDRESS+0x3C)) +#define pISR_TICK (*(unsigned *)(_ISR_STARTADDRESS+0x40)) +#define pISR_WDT (*(unsigned *)(_ISR_STARTADDRESS+0x44)) +#define pISR_TIMER0 (*(unsigned *)(_ISR_STARTADDRESS+0x48)) +#define pISR_TIMER1 (*(unsigned *)(_ISR_STARTADDRESS+0x4C)) +#define pISR_TIMER2 (*(unsigned *)(_ISR_STARTADDRESS+0x50)) +#define pISR_TIMER3 (*(unsigned *)(_ISR_STARTADDRESS+0x54)) +#define pISR_TIMER4 (*(unsigned *)(_ISR_STARTADDRESS+0x58)) +#define pISR_UART2 (*(unsigned *)(_ISR_STARTADDRESS+0x5C)) +#define pISR_NOTUSED (*(unsigned *)(_ISR_STARTADDRESS+0x60)) +#define pISR_DMA0 (*(unsigned *)(_ISR_STARTADDRESS+0x64)) +#define pISR_DMA1 (*(unsigned *)(_ISR_STARTADDRESS+0x68)) +#define pISR_DMA2 (*(unsigned *)(_ISR_STARTADDRESS+0x6C)) +#define pISR_DMA3 (*(unsigned *)(_ISR_STARTADDRESS+0x70)) +#define pISR_SDI (*(unsigned *)(_ISR_STARTADDRESS+0x74)) +#define pISR_SPI0 (*(unsigned *)(_ISR_STARTADDRESS+0x78)) +#define pISR_UART1 (*(unsigned *)(_ISR_STARTADDRESS+0x7C)) +#define pISR_USBD (*(unsigned *)(_ISR_STARTADDRESS+0x84)) +#define pISR_USBH (*(unsigned *)(_ISR_STARTADDRESS+0x88)) +#define pISR_IIC (*(unsigned *)(_ISR_STARTADDRESS+0x8C)) +#define pISR_UART0 (*(unsigned *)(_ISR_STARTADDRESS+0x90)) +#define pISR_SPI1 (*(unsigned *)(_ISR_STARTADDRESS+0x94)) +#define pISR_RTC (*(unsigned *)(_ISR_STARTADDRESS+0x98)) +#define pISR_ADC (*(unsigned *)(_ISR_STARTADDRESS+0xA0)) + + +/* PENDING BIT */ +#define BIT_EINT0 (0x1) +#define BIT_EINT1 (0x1<<1) +#define BIT_EINT2 (0x1<<2) +#define BIT_EINT3 (0x1<<3) +#define BIT_EINT4_7 (0x1<<4) +#define BIT_EINT8_23 (0x1<<5) +#define BIT_BAT_FLT (0x1<<7) +#define BIT_TICK (0x1<<8) +#define BIT_WDT (0x1<<9) +#define BIT_TIMER0 (0x1<<10) +#define BIT_TIMER1 (0x1<<11) +#define BIT_TIMER2 (0x1<<12) +#define BIT_TIMER3 (0x1<<13) +#define BIT_TIMER4 (0x1<<14) +#define BIT_UART2 (0x1<<15) +#define BIT_LCD (0x1<<16) +#define BIT_DMA0 (0x1<<17) +#define BIT_DMA1 (0x1<<18) +#define BIT_DMA2 (0x1<<19) +#define BIT_DMA3 (0x1<<20) +#define BIT_SDI (0x1<<21) +#define BIT_SPI0 (0x1<<22) +#define BIT_UART1 (0x1<<23) +#define BIT_USBD (0x1<<25) +#define BIT_USBH (0x1<<26) +#define BIT_IIC (0x1<<27) +#define BIT_UART0 (0x1<<28) +#define BIT_SPI1 (0x1<<29) +#define BIT_RTC (0x1<<30) +#define BIT_ADC (0x1<<31) +#define BIT_ALLMSK (0xFFFFFFFF) + +#define ClearPending(bit) {\ + rSRCPND = bit;\ + rINTPND = bit;\ + rINTPND;\ + } +/* Wait until rINTPND is changed for the case that the ISR is very short. */ +#ifndef __asm__ +/* Typedefs */ +typedef union { + struct _reg { + unsigned SM_BIT:1; /* Enters STOP mode. This bit isn't be */ + /* cleared automatically. */ + unsigned Reserved:1; /* SL_IDLE mode option. This bit isn't cleared */ + /* automatically. To enter SL_IDLE mode, */ + /* CLKCON register has to be 0xe. */ + unsigned IDLE_BIT:1; /* Enters IDLE mode. This bit isn't be cleared */ + /* automatically. */ + unsigned POWER_OFF:1; + unsigned NAND_flash:1; + unsigned LCDC:1; /* Controls HCLK into LCDC block */ + unsigned USB_host:1; /* Controls HCLK into USB host block */ + unsigned USB_device:1; /* Controls PCLK into USB device block */ + unsigned PWMTIMER:1; /* Controls PCLK into PWMTIMER block */ + unsigned SDI:1; /* Controls PCLK into MMC interface block */ + unsigned UART0:1; /* Controls PCLK into UART0 block */ + unsigned UART1:1; /* Controls PCLK into UART1 block */ + unsigned UART2:1; /* Controls PCLK into UART1 block */ + unsigned GPIO:1; /* Controls PCLK into GPIO block */ + unsigned RTC:1; /* Controls PCLK into RTC control block. Even if */ + /* this bit is cleared to 0, RTC timer is alive. */ + unsigned ADC:1; /* Controls PCLK into ADC block */ + unsigned IIC:1; /* Controls PCLK into IIC block */ + unsigned IIS:1; /* Controls PCLK into IIS block */ + unsigned SPI:1; /* Controls PCLK into SPI block */ + } reg; + unsigned long all; +} CLKCON; + +typedef union +{ + struct { + unsigned ENVID:1; /* LCD video output and the logic 1=enable/0=disable. */ + unsigned BPPMODE:4; /* 1011 = 8 bpp for TFT, 1100 = 16 bpp for TFT, */ + /* 1110 = 16 bpp TFT skipmode */ + unsigned PNRMODE:2; /* TFT: 3 */ + unsigned MMODE:1; /* This bit determines the toggle rate of the VM. */ + /* 0 = Each Frame, 1 = The rate defined by the MVAL */ + unsigned CLKVAL:10; /* TFT: VCLK = HCLK / [(CLKVAL+1) x 2] (CLKVAL >= 1) */ + unsigned LINECNT:10; /* (read only) These bits provide the status of the */ + /* line counter. Down count from LINEVAL to 0 */ + } reg; + unsigned long all; +} LCDCON1; + +typedef union { + struct { + unsigned VSPW:6; /* TFT: Vertical sync pulse width determines the */ + /* VSYNC pulse's high level width by counting the */ + /* number of inactive lines. */ + unsigned VFPD:8; /* TFT: Vertical front porch is the number of */ + /* inactive lines at the end of a frame, before */ + /* vertical synchronization period. */ + unsigned LINEVAL:10; /* TFT/STN: These bits determine the vertical size */ + /* of LCD panel. */ + unsigned VBPD:8; /* TFT: Vertical back porch is the number of inactive */ + /* lines at the start of a frame, after */ + /* vertical synchronization period. */ + } reg; + unsigned long all; +} LCDCON2; + +typedef union { + struct { + unsigned HFPD:8; /* TFT: Horizontal front porch is the number of */ + /* VCLK periods between the end of active data */ + /* and the rising edge of HSYNC. */ + unsigned HOZVAL:11; /* TFT/STN: These bits determine the horizontal */ + /* size of LCD panel. 2n bytes. */ + unsigned HBPD:7; /* TFT: Horizontal back porch is the number of VCLK */ + /* periods between the falling edge of HSYNC and */ + /* the start of active data. */ + } reg; + unsigned long all; +} LCDCON3; + +typedef union { + struct { + unsigned HSPW:8; /* TFT: Horizontal sync pulse width determines the */ + /* HSYNC pulse's high level width by counting the */ + /* number of the VCLK. */ + unsigned MVAL:8; /* STN: */ + } reg; + unsigned long all; +} LCDCON4; + +typedef union { + struct { + unsigned HWSWP:1; /* STN/TFT: Half-Word swap control bit. */ + /* 0 = Swap Disable 1 = Swap Enable */ + unsigned BSWP:1; /* STN/TFT: Byte swap control bit. */ + /* 0 = Swap Disable 1 = Swap Enable */ + unsigned ENLEND:1; /* TFT: LEND output signal enable/disable. */ + /* 0 = Disable LEND signal. */ + /* 1 = Enable LEND signal */ + unsigned PWREN:1; + unsigned INVLEND:1;/* TFT: This bit indicates the LEND signal */ + /* polarity. 0 = normal 1 = inverted */ + unsigned INVPWREN:1; + unsigned INVVDEN:1; /* TFT: This bit indicates the VDEN signal */ + /* polarity. */ + /* 0 = normal 1 = inverted */ + unsigned INVVD:1; /* STN/TFT: This bit indicates the VD (video data) */ + /* pulse polarity. 0 = Normal. */ + /* 1 = VD is inverted. */ + unsigned INVVFRAME:1; /* STN/TFT: This bit indicates the VFRAME/VSYNC */ + /* pulse polarity. 0 = normal 1 = inverted */ + unsigned INVVLINE:1; /* STN/TFT: This bit indicates the VLINE/HSYNC */ + /* pulse polarity. 0 = normal 1 = inverted */ + unsigned INVVCLK:1; /* STN/TFT: This bit controls the polarity of the */ + /* VCLK active edge. 0 = The video data is */ + /* fetched at VCLK falling edge. 1 = The video */ + /* data is fetched at VCLK rising edge */ + unsigned FRM565:1; + unsigned BPP24BL:1; + unsigned HSTATUS:2; /* TFT: Horizontal Status (Read only) */ + /* 00 = HSYNC */ + /* 01 = BACK Porch. */ + /* 10 = ACTIVE */ + /* 11 = FRONT Porch */ + unsigned VSTATUS:2; /* TFT: Vertical Status (Read only). */ + /* 00 = VSYNC */ + /* 01 = BACK Porch. */ + /* 10 = ACTIVE */ + /* 11 = FRONT Porch */ + unsigned RESERVED:16; + } reg; + unsigned long all; +} LCDCON5; + +typedef union { + struct { + unsigned LCDBASEU:21; /* For single-scan LCD: These bits indicate */ + /* A[21:1] of the start address of the LCD */ + /* frame buffer. */ + unsigned LCDBANK:9; /* A[28:22] */ + } reg; + unsigned long all; +} LCDSADDR1; + +typedef union { + struct { + unsigned LCDBASEL:21; /* For single scan LCD: These bits indicate A[21:1]*/ + /* of the end address of the LCD frame buffer. */ + /* LCDBASEL = ((the fame end address) >>1) + 1 */ + /* = LCDBASEU + (PAGEWIDTH+OFFSIZE)x(LINEVAL+1) */ + } reg; + unsigned long all; +} LCDSADDR2; + +typedef union { + struct { + unsigned PAGEWIDTH:11; /* Virtual screen page width(the number of half */ + /* words) This value defines the width of the */ + /* view port in the frame */ + unsigned OFFSIZE:11; /* Virtual screen offset size(the number of half */ + /* words) This value defines the difference */ + /* between the address of the last half word */ + /* displayed on the previous LCD line and the */ + /* address of the first half word to be */ + /* displayed in the new LCD line. */ + } reg; + unsigned long all; +} LCDSADDR3; + +/* + * + */ + +typedef union { + struct { + unsigned IISIFENA:1; /* IIS interface enable (start) */ + unsigned IISPSENA:1; /* IIS prescaler enable */ + unsigned RXCHIDLE:1; /* Receive channel idle command */ + unsigned TXCHIDLE:1; /* Transmit channel idle command */ + unsigned RXDMAENA:1; /* Receive DMA service request enable */ + unsigned TXDMAENA:1; /* Transmit DMA service request enable */ + unsigned RXFIFORDY:1; /* Receive FIFO ready flag (read only) */ + unsigned TXFIFORDY:1; /* Transmit FIFO ready flag (read only) */ + unsigned LRINDEX:1; /* Left/right channel index (read only) */ + } reg; + unsigned long all; +} IISCON; + +typedef union { + struct { + unsigned SBCLKFS:2; /* Serial bit clock frequency select */ + unsigned MCLKFS:1; /* Master clock frequency select */ + unsigned SDBITS:1; /* Serial data bit per channel */ + unsigned SIFMT:1; /* Serial interface format */ + unsigned ACTLEVCH:1; /* Active level pf left/right channel */ + unsigned TXRXMODE:2; /* Transmit/receive mode select */ + unsigned MODE:1; /* Master/slave mode select */ + } reg; + unsigned long all; +} IISMOD; + +typedef union { + struct { + unsigned PSB:5; /* Prescaler control B */ + unsigned PSA:5; /* Prescaler control A */ + } reg; + unsigned long all; +} IISPSR; + +typedef union { + struct { + unsigned RXFIFOCNT:6; /* (read only) */ + unsigned TXFIFOCNT:6; /* (read only) */ + unsigned RXFIFOENA:1; /* */ + unsigned TXFIFOENA:1; /* */ + unsigned RXFIFOMODE:1; /* */ + unsigned TXFIFOMODE:1; /* */ + } reg; + unsigned long all; +} IISSFIFCON; + +typedef union { + struct { + unsigned FENTRY:16; /* */ + } reg; + unsigned long all; +} IISSFIF; +#endif /*__asm__*/ + +#define LCD_WIDTH 240 +#define LCD_HEIGHT 320 +#define LCD_ASPECT ((float)(LCD_WIDTH/LCD_HEIGHT)) + +#define SMDK2410_KEY_SELECT 512 +#define SMDK2410_KEY_START 256 +#define SMDK2410_KEY_A 64 +#define SMDK2410_KEY_B 32 +#define SMDK2410_KEY_L 16 +#define SMDK2410_KEY_R 128 +#define SMDK2410_KEY_UP 8 +#define SMDK2410_KEY_DOWN 2 +#define SMDK2410_KEY_LEFT 1 +#define SMDK2410_KEY_RIGHT 4 + +#endif /*S3C2410_H_*/ diff --git a/c/src/lib/libcpu/arm/s3c24xx/include/s3c24xx.h b/c/src/lib/libcpu/arm/s3c24xx/include/s3c24xx.h index 914b867..753ac1d 100644 --- a/c/src/lib/libcpu/arm/s3c24xx/include/s3c24xx.h +++ b/c/src/lib/libcpu/arm/s3c24xx/include/s3c24xx.h @@ -12,6 +12,8 @@ #include<s3c2400.h> #elif defined CPU_S3C2410 #include<s3c2410.h> +#elif defined CPU_S3C2440 +#include<s3c2440.h> #endif #endif /*S3C24XX_H_*/ diff --git a/c/src/lib/libcpu/arm/s3c24xx/irq/irq.h b/c/src/lib/libcpu/arm/s3c24xx/irq/irq.h index 8882b43..c301038 100644 --- a/c/src/lib/libcpu/arm/s3c24xx/irq/irq.h +++ b/c/src/lib/libcpu/arm/s3c24xx/irq/irq.h @@ -86,6 +86,40 @@ #define BSP_INT_RTC 30 #define BSP_INT_ADC 31 #define BSP_MAX_INT 32 + +#elif defined CPU_S3C2440 + /* possible interrupt sources */ +#define BSP_EINT0 0 +#define BSP_EINT1 1 +#define BSP_EINT2 2 +#define BSP_EINT3 3 +#define BSP_EINT4_7 4 +#define BSP_EINT8_23 5 +#define BSP_nBATT_FLT 7 +#define BSP_INT_TICK 8 +#define BSP_INT_WDT 9 +#define BSP_INT_TIMER0 10 +#define BSP_INT_TIMER1 11 +#define BSP_INT_TIMER2 12 +#define BSP_INT_TIMER3 13 +#define BSP_INT_TIMER4 14 +#define BSP_INT_UART2 15 +#define BSP_INT_LCD 16 +#define BSP_INT_DMA0 17 +#define BSP_INT_DMA1 18 +#define BSP_INT_DMA2 19 +#define BSP_INT_DMA3 20 +#define BSP_INT_SDI 21 +#define BSP_INT_SPI0 22 +#define BSP_INT_UART1 23 +#define BSP_INT_USBD 25 +#define BSP_INT_USBH 26 +#define BSP_INT_IIC 27 +#define BSP_INT_UART0 28 +#define BSP_INT_SPI1 29 +#define BSP_INT_RTC 30 +#define BSP_INT_ADC 31 +#define BSP_MAX_INT 32 #endif #define BSP_INTERRUPT_VECTOR_MIN 0