[rtems commit] pc386: Add Edison base support

Joel Sherril joel at rtems.org
Sun Jan 4 19:45:21 UTC 2015


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

Author:    Joel Sherrill <joel.sherrill at oarcorp.com>
Date:      Sun Dec 14 16:27:06 2014 -0600

pc386: Add Edison base support

The current support for the Edison supports a single polled
UART for input and output plus a simulated clock tick. The
activities forward for supporting the Edison have been posted
on the RTEMS mailing lists and at:

http://rtemsramblings.blogspot.com/2014/12/intel-edison-and-rtems-road-forward.html

---

 c/src/lib/libbsp/i386/pc386/Makefile.am            | 11 ++-
 c/src/lib/libbsp/i386/pc386/configure.ac           | 10 +++
 c/src/lib/libbsp/i386/pc386/console/conscfg.c      | 25 ++++++
 .../lib/libbsp/i386/pc386/console/console_edison.c | 94 ++++++++++++++++++++++
 .../lib/libbsp/i386/pc386/console/printk_support.c | 10 +++
 c/src/lib/libbsp/i386/pc386/include/bsp.h          | 27 ++++++-
 c/src/lib/libbsp/i386/pc386/make/custom/edison.cfg |  5 ++
 c/src/lib/libbsp/i386/pc386/preinstall.am          |  8 +-
 .../lib/libbsp/i386/pc386/startup/bspgetworkarea.c |  4 +
 c/src/lib/libbsp/i386/pc386/startup/bspreset.c     |  6 +-
 c/src/lib/libbsp/i386/pc386/startup/bspstart.c     | 34 ++++++--
 c/src/lib/libbsp/i386/pc386/startup/ldsegs.S       |  3 +
 12 files changed, 220 insertions(+), 17 deletions(-)

diff --git a/c/src/lib/libbsp/i386/pc386/Makefile.am b/c/src/lib/libbsp/i386/pc386/Makefile.am
index 78d0c69..1da40f2 100644
--- a/c/src/lib/libbsp/i386/pc386/Makefile.am
+++ b/c/src/lib/libbsp/i386/pc386/Makefile.am
@@ -68,10 +68,14 @@ noinst_LIBRARIES += libbsp.a
 libbsp_a_SOURCES =
 
 # clock
+if RTEMS_EDISON
+libbsp_a_SOURCES += ../../shared/clock_driver_simidle.c
+else
 libbsp_a_SOURCES += clock/ckinit.c
+endif
+libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
 libbsp_a_SOURCES += clock/todcfg.c
 libbsp_a_SOURCES += ../../shared/tod.c
-libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
 
 include_rtemsdir = $(includedir)/rtems
 include_rtems_HEADERS  =
@@ -80,7 +84,6 @@ if RTEMS_VGA
 include_rtems_HEADERS += console/keyboard.h
 include_rtems_HEADERS += console/kd.h
 include_rtems_HEADERS += console/ps2_drv.h
-include_rtems_HEADERS += ../../shared/console_private.h
 include_rtems_HEADERS += console/vgacons.h
 libbsp_a_SOURCES += console/inch.c
 libbsp_a_SOURCES += console/outch.c
@@ -108,7 +111,11 @@ endif
 endif
 
 # console (non-graphics support)
+if RTEMS_EDISON
+libbsp_a_SOURCES += console/console_edison.c
+endif
 include_HEADERS += ../../i386/shared/comm/i386_io.h
+include_rtems_HEADERS += ../../shared/console_private.h
 libbsp_a_SOURCES += console/serial_mouse_config.c
 libbsp_a_SOURCES += ../../i386/shared/comm/uart.c
 libbsp_a_SOURCES += ../../i386/shared/comm/tty_drv.c
diff --git a/c/src/lib/libbsp/i386/pc386/configure.ac b/c/src/lib/libbsp/i386/pc386/configure.ac
index 9c039c9..f8855ee 100644
--- a/c/src/lib/libbsp/i386/pc386/configure.ac
+++ b/c/src/lib/libbsp/i386/pc386/configure.ac
@@ -17,6 +17,15 @@ RTEMS_PROG_CCAS
 RTEMS_CHECK_NETWORKING
 RTEMS_CHECK_SMP
 
+# Is this an Intel Edison?
+# NOTE: As we learn more, this could be trimmed if more issues
+#       turn out fo lack of legacy peripherals
+RTEMS_BSPOPTS_SET([BSP_IS_EDISON],[edison],[1])
+RTEMS_BSPOPTS_SET([BSP_IS_EDISON],[*],[0])
+RTEMS_BSPOPTS_HELP([BSP_IS_EDISON],[Set if the BSP variant is Intel Edison.])
+AM_CONDITIONAL(RTEMS_EDISON,[test "$BSP_IS_EDISON" = "1"])
+
+RTEMS_BSPOPTS_SET([BSP_ENABLE_VGA],[edison],[0])
 RTEMS_BSPOPTS_SET([BSP_ENABLE_VGA],[*],[1])
 RTEMS_BSPOPTS_HELP([BSP_ENABLE_VGA],
 [Set if the VGA and keyboard console support is enabled.])
@@ -27,6 +36,7 @@ RTEMS_BSPOPTS_HELP([BSP_ENABLE_COM1_COM4],
 [Set if COM1..COM4 support is enabled.])
 AM_CONDITIONAL(RTEMS_VGA,[test "$BSP_ENABLE_COM1_COM4" = "1"])
 
+RTEMS_BSPOPTS_SET([BSP_ENABLE_IDE],[edison],[0])
 RTEMS_BSPOPTS_SET([BSP_ENABLE_IDE],[*],[1])
 RTEMS_BSPOPTS_HELP([BSP_ENABLE_IDE],
 [Set if IDE support is enabled.])
diff --git a/c/src/lib/libbsp/i386/pc386/console/conscfg.c b/c/src/lib/libbsp/i386/pc386/console/conscfg.c
index a34f0e5..d5586d7 100644
--- a/c/src/lib/libbsp/i386/pc386/console/conscfg.c
+++ b/c/src/lib/libbsp/i386/pc386/console/conscfg.c
@@ -60,7 +60,32 @@
   }
 #endif
 
+#if (BSP_IS_EDISON == 1 )
+  extern const console_fns edison_fns;
+#endif
+
 console_tbl     Console_Configuration_Ports[] = {
+#if (BSP_IS_EDISON == 1)
+  {
+    "/dev/vgacons",                        /* sDeviceName */
+    -1,                                     /* deviceType */
+    &edison_fns,                           /* pDeviceFns */
+    NULL,                                  /* deviceProbe */
+    NULL,                                  /* pDeviceFlow */
+    16,                                    /* ulMargin */
+    8,                                     /* ulHysteresis */
+    (void *) NULL,              /* NULL */ /* pDeviceParams */
+    0x00000000,                            /* ulCtrlPort1 */
+    0x00000000,                            /* ulCtrlPort2 */
+    0x00000000,                            /* ulDataPort */
+    NULL,                                  /* getRegister */
+    NULL,                                  /* setRegister */
+    NULL,/* unused */                      /* getData */
+    NULL,/* unused */                      /* setData */
+    0X0,                                   /* ulClock */
+    0x0                                     /* ulIntVector -- base for port */
+  },
+#endif
 #if BSP_ENABLE_VGA
   {
     "/dev/vgacons",                        /* sDeviceName */
diff --git a/c/src/lib/libbsp/i386/pc386/console/console_edison.c b/c/src/lib/libbsp/i386/pc386/console/console_edison.c
new file mode 100644
index 0000000..d5e44ae
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/console_edison.c
@@ -0,0 +1,94 @@
+
+#include <bsp.h>
+#include <libchip/serial.h>
+
+/* XXX hack until real support is available, code copied from libchip */
+#define NS16550_RECEIVE_BUFFER   0
+#define NS16550_TRANSMIT_BUFFER  0
+#define NS16550_INTERRUPT_ENABLE 1
+#define NS16550_INTERRUPT_ID     2
+#define NS16550_FIFO_CONTROL     2
+#define NS16550_LINE_CONTROL     3
+#define NS16550_MODEM_CONTROL    4
+#define NS16550_LINE_STATUS      5
+#define NS16550_MODEM_STATUS     6
+#define NS16550_SCRATCH_PAD      7
+#define NS16550_FRACTIONAL_DIVIDER 10
+
+/* status bits we use in line status */
+
+#define SP_LSR_TX     0x40
+#define SP_LSR_THOLD  0x20
+#define SP_LSR_RDY    0x01
+static volatile uint8_t *edison_com = (volatile uint8_t *)0xff010180;
+
+void edison_write_polled(int minor, char cChar);
+int edison_inbyte_nonblocking_polled(int minor);
+
+static int edison_open(int major, int minor, void *arg)
+{
+  return 0;
+}
+
+static int edison_close(int major, int minor, void *arg)
+{
+  return 0;
+}
+
+int edison_inbyte_nonblocking_polled(int minor)
+{
+  if ( edison_com[NS16550_LINE_STATUS] & 0x01 )
+    return (int) edison_com[NS16550_RECEIVE_BUFFER];
+  return -1;
+}
+
+static ssize_t edison_write_support_polled(int minor, const char *buf, size_t len)
+{
+  ssize_t i;
+
+  for ( i=0 ; i<len ; i++ ) {
+#if 0
+    if ( (edison_com[NS16550_LINE_STATUS] & SP_LSR_TX) == 0 )
+      break;
+#else
+    while ( (edison_com[NS16550_LINE_STATUS] & SP_LSR_TX) == 0x00 )
+      /* wait until ready */;
+#endif
+    edison_com[NS16550_TRANSMIT_BUFFER] = (uint8_t) buf[i];
+  }
+  return i;
+}
+
+static void edison_init(int minor)
+{
+}
+
+void edison_write_polled(int minor, char cChar)
+{
+  while ( (edison_com[NS16550_LINE_STATUS] & SP_LSR_TX) == 0x00 )
+    /* wait until ready */;
+  edison_com[NS16550_TRANSMIT_BUFFER] = (uint8_t) cChar;
+}
+
+static bool edison_probe(int minor)
+{
+  return true;
+}
+
+static int edison_set_attributes(int minor, const struct termios *t)
+{
+  return 0;
+}
+
+const console_fns edison_fns =
+{
+  edison_probe,                       /* deviceProbe */
+  edison_open,                        /* deviceFirstOpen */
+  edison_close,                       /* deviceLastClose */
+  edison_inbyte_nonblocking_polled,   /* deviceRead */
+  edison_write_support_polled,        /* deviceWrite */
+  edison_init,                        /* deviceInitialize */
+  edison_write_polled,                /* deviceWritePolled */
+  edison_set_attributes,              /* deviceSetAttributes */
+  FALSE,                              /* deviceOutputUsesInterrupts */
+};
diff --git a/c/src/lib/libbsp/i386/pc386/console/printk_support.c b/c/src/lib/libbsp/i386/pc386/console/printk_support.c
index c6b0fe5..d4adf55 100644
--- a/c/src/lib/libbsp/i386/pc386/console/printk_support.c
+++ b/c/src/lib/libbsp/i386/pc386/console/printk_support.c
@@ -29,6 +29,11 @@
 
 rtems_device_minor_number         BSPPrintkPort = 0;
 
+#if (BSP_IS_EDISON == 1)
+void edison_write_polled(int minor, char cChar); /* XXX */
+int edison_inbyte_nonblocking_polled(int minor);
+#endif
+
 #if BSP_ENABLE_COM1_COM4
 int ns16550_inbyte_nonblocking_polled( int minor );
 #endif
@@ -66,6 +71,11 @@ int BSP_inch(void)
       } while (result == -1);
     }
   #endif
+  #if (BSP_IS_EDISON == 1)
+    do {
+      result = edison_inbyte_nonblocking_polled( BSPPrintkPort );
+    } while (result == -1);
+  #endif
   return result;
 }
 
diff --git a/c/src/lib/libbsp/i386/pc386/include/bsp.h b/c/src/lib/libbsp/i386/pc386/include/bsp.h
index db08799..f537eb6 100644
--- a/c/src/lib/libbsp/i386/pc386/include/bsp.h
+++ b/c/src/lib/libbsp/i386/pc386/include/bsp.h
@@ -189,8 +189,31 @@ void rtems_irq_mngt_init(void);          /* from 'irq_init.c' */
 
 void bsp_size_memory(void);              /* from 'bspstart.c' */
 
-void Clock_driver_install_handler(void); /* from 'ckinit.c'  */
-void Clock_driver_support_initialize_hardware(void); /* from 'ckinit.c'  */
+#if (BSP_IS_EDISON == 0)
+  void Clock_driver_install_handler(void);             /* from 'ckinit.c'  */
+  void Clock_driver_support_initialize_hardware(void); /* from 'ckinit.c'  */
+#else
+  /**
+   *  @defgroup edison_bsp Clock Tick Support
+   *
+   *  @ingroup i386_pc386
+   *
+   *  @brief Clock Tick Support Package
+   */
+   Thread clock_driver_sim_idle_body(uintptr_t);
+   #define BSP_IDLE_TASK_BODY clock_driver_sim_idle_body
+  /*  
+   * hack to kill some time. Hopefully hitting a hardware register is slower
+   * than an empty loop.
+   */
+  #define BSP_CLOCK_DRIVER_DELAY() \
+    do { \
+      uint64_t _i = 2500000; \
+      while (_i) { \
+        _i--; \
+      } \
+    } while ( 0 )
+#endif /* edison */
 
 void kbd_reset_setup(char *str, int *ints);   /* from 'pc_keyb.c' */
 size_t read_aux(char * buffer, size_t count); /* from 'ps2_mouse.c'  */
diff --git a/c/src/lib/libbsp/i386/pc386/make/custom/edison.cfg b/c/src/lib/libbsp/i386/pc386/make/custom/edison.cfg
new file mode 100644
index 0000000..0a4feed
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/make/custom/edison.cfg
@@ -0,0 +1,5 @@
+#
+#  Configuration file for an Intel Edision
+#
+
+include $(RTEMS_ROOT)/make/custom/pc586-sse.cfg
diff --git a/c/src/lib/libbsp/i386/pc386/preinstall.am b/c/src/lib/libbsp/i386/pc386/preinstall.am
index d20cb77..5305fbe 100644
--- a/c/src/lib/libbsp/i386/pc386/preinstall.am
+++ b/c/src/lib/libbsp/i386/pc386/preinstall.am
@@ -136,10 +136,6 @@ $(PROJECT_INCLUDE)/rtems/ps2_drv.h: console/ps2_drv.h $(PROJECT_INCLUDE)/rtems/$
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/ps2_drv.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/ps2_drv.h
 
-$(PROJECT_INCLUDE)/rtems/console_private.h: ../../shared/console_private.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
-	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/console_private.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/console_private.h
-
 $(PROJECT_INCLUDE)/rtems/vgacons.h: console/vgacons.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/vgacons.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/vgacons.h
@@ -164,6 +160,10 @@ $(PROJECT_INCLUDE)/i386_io.h: ../../i386/shared/comm/i386_io.h $(PROJECT_INCLUDE
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/i386_io.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/i386_io.h
 
+$(PROJECT_INCLUDE)/rtems/console_private.h: ../../shared/console_private.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/console_private.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/console_private.h
+
 $(PROJECT_INCLUDE)/pcibios.h: ../../i386/shared/pci/pcibios.h $(PROJECT_INCLUDE)/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/pcibios.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/pcibios.h
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c b/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
index 0c7c42c..2e4bf5c 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspgetworkarea.c
@@ -56,6 +56,7 @@ void bsp_size_memory(void)
 {
   uintptr_t topAddr;
 
+#if (BSP_IS_EDISON == 0)
   /* Set the value of start of free memory. */
   rtemsWorkAreaStart = (uint32_t)WorkAreaBase + _stack_size;
 
@@ -116,6 +117,9 @@ void bsp_size_memory(void)
     #endif
   }
 
+#else
+    topAddr = (1 * 1024 * 1024 * 1024);
+#endif
   
   bsp_mem_size = topAddr;
 }
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspreset.c b/c/src/lib/libbsp/i386/pc386/startup/bspreset.c
index 266b01c..b11a123 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspreset.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspreset.c
@@ -14,5 +14,9 @@
 void bsp_reset(void)
 {
   /* shutdown and reboot */
-  outport_byte(0x64, 0xFE);      /* use keyboard controler to do the job... */
+  #if (BSP_IS_EDISON == 0)
+    outport_byte(0x64, 0xFE);        /* use keyboard controller */
+  #else
+   *((uint32_t*)0xff009000) = 0xf3;  /* use watchdog */
+  #endif
 }
diff --git a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
index 77b05ad..9b1be64 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
+++ b/c/src/lib/libbsp/i386/pc386/startup/bspstart.c
@@ -34,9 +34,19 @@
 #include <libcpu/cpuModel.h>
 
 /*
- *  External routines
+ * Helper to initialize the PCI Bus
  */
-void Clock_driver_install_handler(void);
+static void bsp_pci_initialize_helper(void)
+{
+#if (BSP_IS_EDISON == 0)
+  int pci_init_retval;
+
+  pci_init_retval = pci_initialize();
+  if (pci_init_retval != PCIB_ERR_SUCCESS) {
+      printk("PCI bus: could not initialize PCI BIOS interface\n");
+  }
+#endif
+}
 
 /*-------------------------------------------------------------------------+
 |         Function: bsp_start
@@ -47,17 +57,26 @@ void Clock_driver_install_handler(void);
 +--------------------------------------------------------------------------*/
 static void bsp_start_default( void )
 {
-  int pci_init_retval;
-
   /*
    *  We need to determine how much memory there is in the system.
    */
   bsp_size_memory();
 
   /*
+   * Turn off watchdog
+   */
+#if (BSP_IS_EDISON == 1)
+  volatile uint32_t *edison_wd = (volatile uint32_t *)0xff009000;
+  *edison_wd = 0x11f8;
+#endif
+
+
+  /*
    * Calibrate variable for 1ms-loop (see timer.c)
    */
+#if (BSP_IS_EDISON == 0)
   Calibrate_loop_1ms();
+#endif
 
   /*
    * Init rtems interrupt management
@@ -72,12 +91,11 @@ static void bsp_start_default( void )
   /*
    * init PCI Bios interface...
    */
-  pci_init_retval = pci_initialize();
-  if (pci_init_retval != PCIB_ERR_SUCCESS) {
-      printk("PCI bus: could not initialize PCI BIOS interface\n");
-  }
+  bsp_pci_initialize_helper();
 
+#if (BSP_IS_EDISON == 0)
   Clock_driver_install_handler();
+#endif
 
 #if BSP_ENABLE_IDE
   bsp_ide_cmdline_init();
diff --git a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S
index 14cbb95..f527ff9 100644
--- a/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S
+++ b/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S
@@ -35,6 +35,7 @@
 
 #include <rtems/asm.h>
 #include <bsp/tblsizes.h> /* contains sizes of GDT and IDT */
+#include <bspopts.h>
 
 /*----------------------------------------------------------------------------+
 | CODE section
@@ -109,6 +110,7 @@ next_step:
 	movw ax, fs
 	movw ax, gs
 
+#if (BSP_IS_EDISON == 0)
 /*---------------------------------------------------------------------+
 | Now we have to reprogram the interrupts :-(. We put them right after
 | the intel-reserved hardware interrupts, at int 0x20-0x2F. There they
@@ -154,6 +156,7 @@ next_step:
 
 	movw	$0xFFFB, SYM(i8259s_cache) /* set up same values in cache */
 
+  #endif
 	jmp	SYM (_establish_stack)	# return to the bsp entry code
 
 /*-------------------------------------------------------------------------+




More information about the vc mailing list