[PATCH 33.2 v2 3/5] LEON3: updated console driver for new AMBAPP layer

Daniel Hellstrom daniel at gaisler.com
Tue Apr 17 14:25:40 UTC 2012


Signed-off-by: Daniel Hellstrom <daniel at gaisler.com>
---
 c/src/lib/libbsp/sparc/leon3/amba/amba.c         |    5 --
 c/src/lib/libbsp/sparc/leon3/console/console.c   |   51 +++++++++++++++++++---
 c/src/lib/libbsp/sparc/leon3/console/debugputs.c |   42 ++++++++---------
 c/src/lib/libbsp/sparc/leon3/include/amba.h      |    1 -
 c/src/lib/libbsp/sparc/leon3/include/bsp.h       |    3 +
 c/src/lib/libbsp/sparc/leon3/include/leon.h      |    7 ---
 c/src/lib/libbsp/sparc/leon3/startup/bspstart.c  |    9 +++-
 7 files changed, 75 insertions(+), 43 deletions(-)

diff --git a/c/src/lib/libbsp/sparc/leon3/amba/amba.c b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
index e41d0aa..60281f3 100644
--- a/c/src/lib/libbsp/sparc/leon3/amba/amba.c
+++ b/c/src/lib/libbsp/sparc/leon3/amba/amba.c
@@ -39,8 +39,6 @@ volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;
  *  amba_ahb_masters, amba_ahb_slaves and amba.
  */
 
-extern int scan_uarts(void);
-
 void amba_initialize(void)
 {
   int icsel;
@@ -95,7 +93,4 @@ void amba_initialize(void)
     ambapp_freq_init(&ambapp_plb, adev,
                      (LEON3_Timer_Regs->scaler_reload + 1) * 1000000);
   }
-
-  /* find UARTS */
-  scan_uarts();
 }
diff --git a/c/src/lib/libbsp/sparc/leon3/console/console.c b/c/src/lib/libbsp/sparc/leon3/console/console.c
index 320aa37..fa67d37 100644
--- a/c/src/lib/libbsp/sparc/leon3/console/console.c
+++ b/c/src/lib/libbsp/sparc/leon3/console/console.c
@@ -62,6 +62,12 @@ extern int apbuart_inbyte_nonblocking(ambapp_apb_uart *regs);
 
 /* body is in debugputs.c */
 
+struct apbuart_priv {
+  ambapp_apb_uart *regs;
+  unsigned int freq_hz;
+};
+static struct apbuart_priv apbuarts[BSP_NUMBER_OF_TERMIOS_PORTS];
+static int uarts = 0;
 
 /*
  *  Console Termios Support Entry Points
@@ -78,7 +84,7 @@ ssize_t console_write_support (int minor, const char *buf, size_t len)
     port = minor - 1;
 
   while (nwrite < len) {
-    apbuart_outbyte_polled((ambapp_apb_uart*)LEON3_Console_Uart[port], *buf++);
+    apbuart_outbyte_polled(apbuarts[port].regs, *buf++);
     nwrite++;
   }
   return nwrite;
@@ -93,15 +99,44 @@ int console_pollRead(int minor)
   else
     port = minor - 1;
 
-  return apbuart_inbyte_nonblocking((ambapp_apb_uart*)LEON3_Console_Uart[port]);
+  return apbuart_inbyte_nonblocking(apbuarts[port].regs);
+}
+
+/* AMBA PP find routine. Extract AMBA PnP information into data structure. */
+int find_matching_apbuart(struct ambapp_dev *dev, int index, void *arg)
+{
+  struct ambapp_apb_info *apb = (struct ambapp_apb_info *)dev->devinfo;
+
+  /* Extract needed information of one APBUART */
+  apbuarts[uarts].regs = (ambapp_apb_uart *)apb->start;
+  /* Get APBUART core frequency, it is assumed that it is the same
+   * as Bus frequency where the UART is situated
+   */
+  apbuarts[uarts].freq_hz = ambapp_freq_get(&ambapp_plb, dev);
+  uarts++;
+
+  if (uarts >= BSP_NUMBER_OF_TERMIOS_PORTS)
+    return 1; /* Satisfied number of UARTs, stop search */
+  else
+    return 0; /* Continue searching for more UARTs */
+}
+
+/* Find all UARTs */
+int console_scan_uarts(void)
+{
+  memset(apbuarts, 0, sizeof(apbuarts));
+
+  /* Find APBUART cores */
+  ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS), VENDOR_GAISLER,
+                  GAISLER_APBUART, find_matching_apbuart, NULL);
+
+  return uarts;
 }
 
 /*
  *  Console Device Driver Entry Points
  *
  */
-int uarts = 0;
-volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
 
 rtems_device_driver console_initialize(
   rtems_device_major_number  major,
@@ -115,6 +150,9 @@ rtems_device_driver console_initialize(
 
   rtems_termios_initialize();
 
+  /* Find UARTs */
+  console_scan_uarts();
+
   /* Update syscon_uart_index to index used as /dev/console
    * Let user select System console by setting syscon_uart_index. If the
    * BSP is to provide the default UART (syscon_uart_index==0):
@@ -190,9 +228,8 @@ rtems_device_driver console_open(
     port = minor - 1;
 
   /* Initialize UART on opening */
-  LEON3_Console_Uart[port]->ctrl |= LEON_REG_UART_CTRL_RE |
-                                     LEON_REG_UART_CTRL_TE;
-  LEON3_Console_Uart[port]->status = 0;
+  apbuarts[port]->regs->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
+  apbuarts[port]->regs->status = 0;
 
   return RTEMS_SUCCESSFUL;
 }
diff --git a/c/src/lib/libbsp/sparc/leon3/console/debugputs.c b/c/src/lib/libbsp/sparc/leon3/console/debugputs.c
index 43c6d7d..c6e0648 100644
--- a/c/src/lib/libbsp/sparc/leon3/console/debugputs.c
+++ b/c/src/lib/libbsp/sparc/leon3/console/debugputs.c
@@ -23,11 +23,6 @@
 #include <assert.h>
 #include <stdio.h>
 
-/*
- * Number of uarts on AMBA bus
- */
-extern int uarts;
-
 static int isinit = 0;
 
 /* Let user override which on-chip APBUART will be debug UART
@@ -40,24 +35,16 @@ static int isinit = 0;
 int debug_uart_index __attribute__((weak)) = 0;
 ambapp_apb_uart *dbg_uart = NULL;
 
-/*
- *  Scan for UARTS in configuration
+/* Initialize the BSP system debug console layer. It will scan AMBA Plu&Play
+ * for a debug APBUART and enable RX/TX for that UART.
  */
-int scan_uarts(void)
+int bsp_debug_uart_init(void)
 {
   int i;
-  amba_apb_device apbuarts[LEON3_APBUARTS];
+  struct ambapp_dev *adev;
+  struct ambapp_apb_info *apb;
 
   if (isinit == 0) {
-    i = 0;
-    uarts = 0;
-
-    uarts = amba_find_apbslvs(
-      &amba_conf, VENDOR_GAISLER, GAISLER_APBUART, apbuarts, LEON3_APBUARTS);
-    for(i=0; i<uarts; i++) {
-      LEON3_Console_Uart[i] = (volatile LEON3_UART_Regs_Map *)apbuarts[i].start;
-    }
-
     /* Update debug_uart_index to index used as debug console.
      * Let user select Debug console by setting debug_uart_index. If the
      * BSP is to provide the default UART (debug_uart_index==0):
@@ -74,16 +61,27 @@ int scan_uarts(void)
       debug_uart_index = debug_uart_index - 1; /* User selected dbg-console */
     }
 
-    /* initialize debug uart if present for printk */
-    if (debug_uart_index < uarts) {
-      dbg_uart = (ambapp_apb_uart *)LEON3_Console_Uart[debug_uart_index];
+    /* Find APBUART core for System Debug Console */
+    i = debug_uart_index;
+    adev = (void *)ambapp_for_each(&ambapp_plb, (OPTIONS_ALL|OPTIONS_APB_SLVS),
+                                   VENDOR_GAISLER, GAISLER_APBUART,
+                                   ambapp_find_by_idx, (void *)&i);
+    if (adev) {
+      /* Found a matching debug console, initialize debug uart if present
+       * for printk
+       */
+      apb = (struct ambapp_apb_info *)adev->devinfo;
+      dbg_uart = (ambapp_apb_uart *)apb->start;
       dbg_uart->ctrl |= LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE;
       dbg_uart->status = 0;
     }
     isinit = 1;
   }
 
-  return uarts;
+  if (dbg_uart == NULL)
+    return 0;
+  else
+    return 1;
 }
 
 /*
diff --git a/c/src/lib/libbsp/sparc/leon3/include/amba.h b/c/src/lib/libbsp/sparc/leon3/include/amba.h
index aa13f2c..32b4a42 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/amba.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/amba.h
@@ -25,7 +25,6 @@
 #define LEON3_AHB_MASTERS 64
 #define LEON3_AHB_SLAVES 64
 #define LEON3_APB_SLAVES 16
-#define LEON3_APBUARTS 8
 
 #include <ambapp.h>
 
diff --git a/c/src/lib/libbsp/sparc/leon3/include/bsp.h b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
index e5ae2c1..d883064 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/bsp.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/bsp.h
@@ -41,6 +41,9 @@ extern "C" {
 void *bsp_idle_thread( uintptr_t ignored );
 #define BSP_IDLE_TASK_BODY bsp_idle_thread
 
+/* Maximum supported APBUARTs by BSP */
+#define BSP_NUMBER_OF_TERMIOS_PORTS 8
+
 /*
  * Network driver configuration
  */
diff --git a/c/src/lib/libbsp/sparc/leon3/include/leon.h b/c/src/lib/libbsp/sparc/leon3/include/leon.h
index 819800c..da752b2 100644
--- a/c/src/lib/libbsp/sparc/leon3/include/leon.h
+++ b/c/src/lib/libbsp/sparc/leon3/include/leon.h
@@ -47,12 +47,6 @@ extern "C" {
     (_trap) <= 0x1F )
 
 typedef struct {
-  volatile unsigned int data;
-  volatile unsigned int status;
-  volatile unsigned int ctrl;
-} LEON3_UART_Regs_Map;
-
-typedef struct {
   volatile unsigned int value;
   volatile unsigned int reload;
   volatile unsigned int conf;
@@ -147,7 +141,6 @@ typedef struct {
 
 extern volatile LEON3_IrqCtrl_Regs_Map *LEON3_IrqCtrl_Regs;  /* LEON3 Interrupt Controller */
 extern volatile LEON3_Timer_Regs_Map *LEON3_Timer_Regs; /* LEON3 GP Timer */
-extern volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];
 
 /* LEON3 CPU Index of boot CPU */
 extern int LEON3_Cpu_Index;
diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bspstart.c b/c/src/lib/libbsp/sparc/leon3/startup/bspstart.c
index 9cad164..50fa5e5 100644
--- a/c/src/lib/libbsp/sparc/leon3/startup/bspstart.c
+++ b/c/src/lib/libbsp/sparc/leon3/startup/bspstart.c
@@ -31,6 +31,7 @@ int CPU_SPARC_HAS_SNOOPING;
 int LEON3_Cpu_Index = 0;
 
 extern void amba_initialize(void);
+extern void bsp_debug_uart_init(void);
 
 /*
  * set_snooping
@@ -75,6 +76,12 @@ void bsp_start( void )
    */
   LEON3_Cpu_Index = (get_asr17() >> 28) & 3;
 
-  /* Find UARTs */
+  /* Scan AMBA Plug&Play and parse it into a RAM description (ambapp_plb),
+   * find GPTIMER for bus frequency, find IRQ Controller and initialize
+   * interrupt support
+   */
   amba_initialize();
+
+  /* find debug UART for printk() */
+  bsp_debug_uart_init();
 }
-- 
1.7.0.4




More information about the devel mailing list