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

Daniel Hellstrom daniel at gaisler.com
Tue Apr 17 11:40:53 UTC 2012


On 04/16/2012 05:31 PM, Joel Sherrill wrote:
> On 04/16/2012 10:09 AM, Gedare Bloom wrote:
>> On Mon, Apr 16, 2012 at 4:49 AM, Daniel Hellstrom<daniel at gaisler.com>  wrote:
>>> On 04/16/2012 01:21 AM, Joel Sherrill wrote:
>>>> On 04/15/2012 01:53 PM, Gedare Bloom wrote:
>>>>> This seems ok. I found BSP_NUMBER_OF_TERMIOS_PORTS a little
>>>>> confusing--does it have any relation with
>>>>> CONFIGURE_NUMBER_OF_TERMIOS_PORTS or just is it similar in name?
>>>>>
>>>> It is intended to be the number known to be on the board
>>>> as a minimum. So rather than CONFIGURE_NUMBER_OF_TERMIOS_PORTS
>>>> defaulting to 1 when you enable console, it defaults to that
>>>> number.
>>>>
>>>> It may make sense to do away with that and let the user
>>>> just fail if they under configure.
>>>>
>>>> It is a component into CONFIGURE_NUMBER_OF_TERMIOS_PORTS.
>>>>
>>>> Dropping it would be OK if it doesn't stop a console from
>>>> initializing at all on a board with N>1 ports when running
>>>> hello world
>>>
>>> BSP_NUMBER_OF_TERMIOS_PORTS is the maximum number of UARTs the BSP supports.
>>> CONFIGURE_NUMBER_OF_TERMIOS_PORTS is termios-internal and is not available
>>> when the BSP builds?
>>>
>> I believe that is the case. The big no-no is for the BSP to define
>> that number itself.
> Right. Consider a PC or any other board which can take add-on cards.
> The BSP knows the UARTs on the base board but cannot account for
> any add-ons.

I agree, and with LEON the on-chip peripherals are plug-and-played like add-on boards.

>
> For example, I know of an RTEMS application with an embedded PC
> that has almost 40 serial ports.
>>
>>> Now that the bsp_early_malloc() patch has been accepted, I might change this
>>> behavior in a future patch so that the private structures are allocated
>>> dynamically after probing how many UARTs are available. Probably it is not
>>> worth probing it, since it may take more space with the extra instructions
>>> than the current excess private data. On the other hand it is one single
>>> function call with the new AMBAPP layer to find the number of cores.
>>>
>>> Another possibility would be if CONFIGURE_NUMBER_OF_TERMIOS_PORTS were saved
>>> in a "configuration structure" I could have dynamically supported the user's
>>> configuration, by using bsp_early_malloc(sizeof(priv) * config->no_ports) in
>>> my UART init code... in the future :)
>>>
>> Yes that might be nice. It should be in one of the configuration
>> structures defined in confdefs. I'm not sure exactly what you have to
>> pull in to use it, I think config.h in the sapi has those structure
>> definitions.
> CONFIGURE_NUMBER_OF_TERMIOS_PORTS is only used to
> reserve enough RTEMS workspace so you can open all
> termios ports concurrently.  This is currently the only use
> since termios only uses semaphores.
>
> #define CONFIGURE_TERMIOS_SEMAPHORES \
>     ((CONFIGURE_NUMBER_OF_TERMIOS_PORTS * 4) + 1)
Ok, I see.

>
> Daniel.. if the user has PCI and plugs in an 8-port UART board,
> then your allocation of memory for those 8 ports is unnecessary.
If a PCI UART add-on board is added, another driver must be used. Since it will probably not be a APBUART on PCI, and the APBUART driver only supports on-chip APBUARTs. However, together with our 
driver manager I am able to reuse the code in the APBUART driver for both on-chip and AMBA-over-PCI devices, in order to support that I have introduced a new console.c (called cons.c).

>
> And whether the hardware has N termios ports or not, the
> application may choose not to use them all and not need
> the reserved workspace.
>
> I would lean to eliminating BSP_NUMBER_OF_TERMIOS_PORTS

Note that I'm not introducing a new limitation here, the old code has always been limited to LEON3_APBUARTS uarts. I have just renamed it to BSP_NUMBER_OF_TERMIOS_PORTS, perhaps I should not have done 
that. Old code:

int uarts = 0;
volatile LEON3_UART_Regs_Map *LEON3_Console_Uart[LEON3_APBUARTS];

I will try to eliminate BSP_NUMBER_OF_TERMIOS_PORTS as soon as I can, now that bsp_early_malloc() is in the BSP, I can make this dynamic. And as Joel say, the number of BSP UARTs should not depend on 
the TERMIOS layer.

Daniel


>>> Thanks,
>>> Daniel
>>>
>>>
>>>>> -Gedare
>>>>>
>>>>> On Tue, Apr 10, 2012 at 7:33 AM, Daniel Hellstrom<daniel at gaisler.com>
>>>>>   wrote:
>>>>>> 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
>>>>>>
>>>>>> _______________________________________________
>>>>>> rtems-devel mailing list
>>>>>> rtems-devel at rtems.org
>>>>>> http://www.rtems.org/mailman/listinfo/rtems-devel
>>>>> _______________________________________________
>>>>> rtems-devel mailing list
>>>>> rtems-devel at rtems.org
>>>>> http://www.rtems.org/mailman/listinfo/rtems-devel
>>>>
>>>>
>
>




More information about the devel mailing list