You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2022/10/27 08:42:48 UTC

[GitHub] [incubator-nuttx] zouboan opened a new pull request, #7443: arch/sparc: add initial support for S698PM chip and SMP

zouboan opened a new pull request, #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443

   ## Summary
   After several weeks of after hours hard work,  I completed initial support of porting nuttx to S698PM,which is a quad-core SPARC-V8 architecture processor,  the maximum frequency is up to 600 MHz. The S698PM is compatible with LEON4, more people can port NuttX to other LEON3/LEON4 chip, such as Dual-Core LEON3FT GR712RC and Quad Core LEON4 GR740. The journey of debug is long and tortuous, but finally succeeded, glory to Lord in the highest!
   ## Impact
   sparc
   ## Testing
   Tested nsh and smp on S698PM-DKIT development board
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] zouboan commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
zouboan commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1006802268


##########
arch/sparc/src/sparc_v8/up_initialstate.c:
##########
@@ -71,7 +71,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == IDLE_PROCESS_ID)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
-                                      (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));
+                           (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));

Review Comment:
   ci long line error



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] zouboan commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
zouboan commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1006811967


##########
arch/sparc/src/sparc_v8/up_initialstate.c:
##########
@@ -71,7 +71,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == IDLE_PROCESS_ID)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
-                                      (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));
+                           (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));

Review Comment:
   i don't  proficient in github,it could be a mess



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] zouboan commented on pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
zouboan commented on PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#issuecomment-1293193421

   ![Screenshot from 2022-10-27 16-34-13](https://user-images.githubusercontent.com/10884769/198237199-aed29c21-dd41-43f5-bb4f-99d6df794f96.png)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1006895682


##########
arch/sparc/src/sparc_v8/up_initialstate.c:
##########
@@ -71,7 +71,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == IDLE_PROCESS_ID)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
-                                      (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));
+                           (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));

Review Comment:
   it's simple:
   git rebase --interactive HEAD~2
   change pick to edit for the first patch
   make the change and git commit --amend
   git rebase --continue



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] zouboan commented on pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
zouboan commented on PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#issuecomment-1293192460

   ![SMP](https://user-images.githubusercontent.com/10884769/198237024-a58770b3-1885-451c-9960-684ecff2633d.JPG)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1006793124


##########
arch/sparc/src/common/up_initialize.c:
##########
@@ -130,6 +140,19 @@ static inline void up_color_intstack(void)
 
 void up_initialize(void)
 {
+#ifdef CONFIG_SMP

Review Comment:
   don't need, the default should be zero



##########
arch/sparc/src/sparc_v8/up_schedulesigaction.c:
##########
@@ -175,3 +175,184 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
 
   leave_critical_section(flags);
 }
+#endif /* !CONFIG_SMP */
+
+#ifdef CONFIG_SMP
+void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
+{
+  irqstate_t flags;
+  int cpu;
+  int me;
+
+  sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
+
+  /* Make sure that interrupts are disabled */
+
+  flags = enter_critical_section();
+
+  /* Refuse to handle nested signal actions */
+
+  if (!tcb->xcp.sigdeliver)
+    {
+      /* First, handle some special cases when the signal is being delivered
+       * to task that is currently executing on any CPU.
+       */
+
+      sinfo("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS);
+
+      if (tcb->task_state == TSTATE_TASK_RUNNING)
+        {
+          me  = this_cpu();
+          cpu = tcb->cpu;
+
+          /* CASE 1:  We are not in an interrupt handler and a task is
+           * signaling itself for some reason.
+           */
+
+          if (cpu == me && !CURRENT_REGS)
+            {
+              /* In this case just deliver the signal now.
+               * REVISIT:  Signal handler will run in a critical section!
+               */
+
+              sigdeliver(tcb);
+            }
+
+          /* CASE 2:  The task that needs to receive the signal is running.
+           * This could happen if the task is running on another CPU OR if
+           * we are in an interrupt handler and the task is running on this
+           * CPU.  In the former case, we will have to PAUSE the other CPU
+           * first.  But in either case, we will have to modify the return
+           * state as well as the state in the TCB.
+           */
+
+          else
+            {
+              /* If we signaling a task running on the other CPU, we have
+               * to PAUSE the other CPU.
+               */
+
+              if (cpu != me)
+                {
+                  /* Pause the CPU */
+
+                  up_cpu_pause(cpu);
+
+                  /* Wait while the pause request is pending */
+
+                  while (up_cpu_pausereq(cpu))
+                    {
+                    }
+
+                  /* Now tcb on the other CPU can be accessed safely */
+
+                  /* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.sigdeliver       = (FAR void *)sigdeliver;
+                  tcb->xcp.saved_pc         = tcb->xcp.regs[REG_PC];
+                  tcb->xcp.saved_npc        = tcb->xcp.regs[REG_NPC];
+                  tcb->xcp.saved_status     = tcb->xcp.regs[REG_PSR];
+
+                  /* Then set up vector to the trampoline with interrupts
+                   * disabled.  We must already be in privileged thread mode
+                   * to be here.
+                   */
+
+                  tcb->xcp.regs[REG_PC]     = (uint32_t)up_sigdeliver;
+                  tcb->xcp.regs[REG_NPC]    = (uint32_t)up_sigdeliver + 4;
+                  tcb->xcp.regs[REG_PSR]    |= SPARC_PSR_ET_MASK;
+                }
+              else
+                {
+                  /* tcb is running on the same CPU */
+
+                  /* Save registers that must be protected while the signal
+                   * handler runs. These will be restored by the signal
+                   * trampoline after the signal(s) have been delivered.
+                   */
+
+                  tcb->xcp.sigdeliver   = (FAR void *)sigdeliver;

Review Comment:
   ditto



##########
arch/sparc/src/sparc_v8/up_schedulesigaction.c:
##########
@@ -175,3 +175,184 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
 
   leave_critical_section(flags);
 }
+#endif /* !CONFIG_SMP */
+
+#ifdef CONFIG_SMP
+void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
+{
+  irqstate_t flags;
+  int cpu;
+  int me;
+
+  sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
+
+  /* Make sure that interrupts are disabled */
+
+  flags = enter_critical_section();
+
+  /* Refuse to handle nested signal actions */
+
+  if (!tcb->xcp.sigdeliver)
+    {
+      /* First, handle some special cases when the signal is being delivered
+       * to task that is currently executing on any CPU.
+       */
+
+      sinfo("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS);
+
+      if (tcb->task_state == TSTATE_TASK_RUNNING)
+        {
+          me  = this_cpu();
+          cpu = tcb->cpu;
+
+          /* CASE 1:  We are not in an interrupt handler and a task is
+           * signaling itself for some reason.
+           */
+
+          if (cpu == me && !CURRENT_REGS)
+            {
+              /* In this case just deliver the signal now.
+               * REVISIT:  Signal handler will run in a critical section!
+               */
+
+              sigdeliver(tcb);
+            }
+
+          /* CASE 2:  The task that needs to receive the signal is running.
+           * This could happen if the task is running on another CPU OR if
+           * we are in an interrupt handler and the task is running on this
+           * CPU.  In the former case, we will have to PAUSE the other CPU
+           * first.  But in either case, we will have to modify the return
+           * state as well as the state in the TCB.
+           */
+
+          else
+            {
+              /* If we signaling a task running on the other CPU, we have
+               * to PAUSE the other CPU.
+               */
+
+              if (cpu != me)
+                {
+                  /* Pause the CPU */
+
+                  up_cpu_pause(cpu);
+
+                  /* Wait while the pause request is pending */
+
+                  while (up_cpu_pausereq(cpu))
+                    {
+                    }
+
+                  /* Now tcb on the other CPU can be accessed safely */
+
+                  /* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.sigdeliver       = (FAR void *)sigdeliver;

Review Comment:
   remove all FAR



##########
arch/sparc/src/sparc_v8/up_initialstate.c:
##########
@@ -71,7 +71,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == IDLE_PROCESS_ID)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
-                                      (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));
+                           (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));

Review Comment:
   why change?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] zouboan commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
zouboan commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1007585797


##########
arch/sparc/src/sparc_v8/up_initialstate.c:
##########
@@ -71,7 +71,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == IDLE_PROCESS_ID)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
-                                      (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));
+                           (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));

Review Comment:
   it means i should fix->commit->rebase->squash->amend file one by one, rather than fix all file and the rebase?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1006931732


##########
arch/sparc/src/s698pm/chip.h:
##########
@@ -0,0 +1,48 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/chip.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_SPARC_SRC_S698PM_CHIP_H
+#define __ARCH_SPARC_SRC_S698PM_CHIP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/* Include only the memory map.  Other chip hardware files should then
+ * include this file for the proper setup
+ */
+
+#include "s698pm-memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Define features for supported chip in the SPARC family */
+
+#if 1
+#else
+#  error "Unsupported SPARC chip"
+#endif

Review Comment:
   Which features? Maybe it could be removed for now.



##########
arch/sparc/src/s698pm/s698pm-irq.c:
##########
@@ -0,0 +1,533 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/s698pm-irq.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include <arch/irq.h>
+
+#include "up_internal.h"
+#include "s698pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+
+#if defined(CONFIG_SMP)
+#  define INTSTACK_ALLOC (CONFIG_SMP_NCPUS * INTSTACK_SIZE)
+#else
+#  define INTSTACK_ALLOC (INTSTACK_SIZE)
+#endif
+
+#endif
+
+/* IRQ to CPU and CPU interrupts mapping:
+ *
+ * Encoding: CCCIIIII
+ *  C: CPU that enabled the interrupt (0 ~ 3).
+ *  I: Associated CPU interrupt (0 ~ 31).
+ */
+
+#define IRQ_UNMAPPED      0xff
+#define IRQ_GETCPU(m)     (((m) & 0xe0) >> 0x05)
+#define IRQ_GETCPUINT(m)  ((m) & 0x1f)
+#define IRQ_MKMAP(c, i)   (((c) << 0x05) | (i))
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+static volatile uint8_t g_irqmap[NR_IRQS];
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+/* In the SMP configuration, we will need custom interrupt stacks.
+ * These definitions provide the aligned stack allocations.
+ */
+
+static uint64_t g_intstack_alloc[INTSTACK_ALLOC >> 3];
+
+/* These definitions provide the "top" of the push-down stacks. */
+
+uintptr_t g_cpu_intstack_top[CONFIG_SMP_NCPUS] =
+{
+  (uintptr_t)g_intstack_alloc + INTSTACK_SIZE,
+#if defined(CONFIG_SMP)
+
+#if CONFIG_SMP_NCPUS > 1
+  (uintptr_t)g_intstack_alloc + (2 * INTSTACK_SIZE),
+#if CONFIG_SMP_NCPUS > 2
+  (uintptr_t)g_intstack_alloc + (3 * INTSTACK_SIZE),
+#if CONFIG_SMP_NCPUS > 3
+  (uintptr_t)g_intstack_alloc + (4 * INTSTACK_SIZE),
+#endif /* CONFIG_SMP_NCPUS > 3 */
+#endif /* CONFIG_SMP_NCPUS > 2 */
+#endif /* CONFIG_SMP_NCPUS > 1 */
+
+#endif /* defined(CONFIG_SMP) */
+};
+#endif /* if CONFIG_ARCH_INTERRUPTSTACK > 7 */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_IRQPRIO
+static int up_prioritize_irq(int irq, int priority);
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_irqinitialize
+ ****************************************************************************/
+
+void up_irqinitialize(void)
+{
+  int irq = 0;
+
+  for (irq = 0; irq < NR_IRQS; irq++)
+    {
+      g_irqmap[irq] = IRQ_UNMAPPED;
+    }
+
+  /* Initialize CPU interrupts */
+
+  s698pm_cpuint_initialize();
+
+  /* Set interrupts priority */
+
+  for (irq = 0x11; irq < 0x20; irq++)
+    {
+      /* Set all interrupts to the default (low) priority */
+
+      (void)up_prioritize_irq(irq, 0);
+    }
+
+  /* Attach software interrupts */
+
+  irq_attach(S698PM_IRQ_SW_SYSCALL_TA0, up_swint0, NULL);
+  irq_attach(S698PM_IRQ_SW_SYSCALL_TA8, up_swint1, NULL);
+
+  /* And finally, enable cpu interrupts */
+
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+  up_irq_enable();
+#endif
+}
+
+/****************************************************************************
+ * Name:  s698pm_cpuint_initialize
+ *
+ * Description:
+ *   Initialize CPU interrupts
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success; A negated errno value is returned on
+ *   any failure.
+ *
+ ****************************************************************************/
+
+int s698pm_cpuint_initialize(void)
+{
+  uintptr_t regaddr;
+  int cpu = 0;
+
+#ifdef CONFIG_SMP
+  /* Which CPU are we initializing */
+
+  cpu = up_cpu_index();
+  DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS);
+#endif
+
+  /* get Interrupt_Mask reg address of cpu */
+
+  regaddr = S698PM_IRQREG_P0_MASK + 4 * cpu;
+
+  /* Disable all CPU interrupts on this CPU */
+
+  putreg32(0, regaddr);
+
+#if defined CONFIG_SMP
+  /* Attach IPI interrupts */
+
+  irq_attach(S698PM_IPI_IRQ, s698pm_pause_handler, NULL);
+
+  (void)s698pm_setup_irq(cpu, S698PM_IPI_IRQ, 0);
+
+  /* And enable the IPI interrupt */
+
+  up_enable_irq(S698PM_IPI_IRQ);
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name:  s698pm_setup_irq
+ *
+ * Description:
+ *   This function sets up the IRQ. It allocates a CPU interrupt of the given
+ *   priority andattaches it to the given irq.
+ *
+ * Input Parameters:
+ *   cpu      - The CPU to receive the interrupt 0~3
+ *   irq      - The irq number from irq.h to be assigned to a EXT interrupt.
+ *   priority - Interrupt's priority (0~1).
+ *
+ * Returned Value:
+ *   The allocated CPU interrupt on success, a negated errno value on
+ *   failure.
+ *
+ ****************************************************************************/
+
+int s698pm_setup_irq(int cpu, int irq, int priority)
+{
+  irqstate_t irqstate;
+  int cpuint;
+
+  irqstate = enter_critical_section();
+
+  if (irq >= S698PM_IRQ_FIRST_INT && irq <= S698PM_IRQ_LAST_INT)
+    {
+      cpuint = irq - S698PM_IRQ_FIRST_INT + 1;
+    }
+  else if (irq > S698PM_IRQ_LAST && irq < NR_IRQS)
+    {
+      cpuint = irq - 240;

Review Comment:
   What is 240? Please avoid hard-coded value that could be difficult to track later



##########
arch/sparc/src/s698pm/s698pm-serial.c:
##########
@@ -0,0 +1,1037 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/s698pm-serial.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+#  include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <nuttx/spinlock.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "s698pm-config.h"
+#include "chip.h"
+#include "s698pm-uart.h"
+#include "s698pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If we are not using the serial driver for the console, then we still must
+ * provide some minimal implementation of up_putc.
+ */
+
+#ifdef USE_SERIALDRIVER
+
+/* Which UART with be tty0/console and which tty1?  The console will always
+ * be ttyS0.  If there is no console then will use the lowest numbered UART.
+ */
+
+/* First pick the console and ttys0.  This could be any of UART1-4 */
+
+#if defined(CONFIG_UART1_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart1port /* UART1 is console */
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart2port /* UART2 is console */
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart3port /* UART3 is console */
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#elif defined(CONFIG_UART4_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart4port /* UART4 is console */
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#else
+#  undef CONSOLE_DEV                        /* No console */
+#  if defined(CONFIG_S698PM_UART1)
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART2)
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART3)
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART4)
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#  endif
+#endif
+
+/* Pick ttys1.  This could be any of UART1-4 excluding the console UART. */
+
+#if defined(CONFIG_S698PM_UART1) && !defined(UART1_ASSIGNED)
+#  define TTYS1_DEV           g_uart1port /* UART1 is ttyS1 */
+#  define UART1_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS1_DEV           g_uart2port /* UART2 is ttyS1 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS1_DEV           g_uart3port /* UART3 is ttyS1 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS1_DEV           g_uart4port /* UART4 is ttyS1 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys2.  This could be one of UART2-4. It can't be UART1 because that
+ * was either assigned as ttyS0 or ttys1.  One of UART 1-4 could also be the
+ * console.
+ */
+
+#if defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS2_DEV           g_uart2port /* UART2 is ttyS2 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS2_DEV           g_uart3port /* UART3 is ttyS2 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS2_DEV           g_uart4port /* UART4 is ttyS2 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys3. This could be one of UART3-4. It can't be UART1-2 because
+ * those have already been assigned to ttsyS0, 1, or 2.  One of
+ * UART 2-4 could also be the console.
+ */
+
+#if defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS3_DEV           g_uart3port /* UART3 is ttyS3 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS3_DEV           g_uart4port /* UART4 is ttyS3 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Common initialization logic will not not know that the all of the UARTs
+ * have been disabled.  So, as a result, we may still have to provide
+ * stub implementations of up_earlyserialinit(), up_serialinit(), and
+ * up_putc().
+ */
+
+#ifdef HAVE_UART_DEVICE
+
+/* These values describe the set of enabled interrupts */
+
+#define RX_ENABLED(im)    (((im) & MSK_UART_ENABLE_RX) != 0)
+#define TX_ENABLED(im)    (((im) & MSK_UART_ENABLE_TX) != 0)
+
+#define ENABLE_RX(im)     do { (im) |= MSK_UART_ENABLE_RX; } while (0)
+#define ENABLE_TX(im)     do { (im) |= MSK_UART_ENABLE_TX; } while (0)
+
+#define DISABLE_RX(im)    do { (im) &= ~MSK_UART_ENABLE_RX; } while (0)
+#define DISABLE_TX(im)    do { (im) &= ~MSK_UART_ENABLE_TX; } while (0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct up_dev_s
+{
+  uintptr_t uartbase;  /* Base address of UART registers */
+  uint32_t  baud;      /* Configured baud */
+  uint8_t   irq;       /* IRQ associated with this UART (for attachment) */
+  uint8_t   im;        /* Interrupt mask state */
+  uint8_t   parity;    /* 0=none, 1=odd, 2=even */
+  uint8_t   bits;      /* Number of bits (5, 6, 7 or 8) */
+  bool      stopbits2; /* true: Configure with 2 stop bits instead of 1 */
+  spinlock_t lock;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers */
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset);
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value);
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im);
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im);
+
+/* Serial driver methods */
+
+static int  up_setup(struct uart_dev_s *dev);
+static void up_shutdown(struct uart_dev_s *dev);
+static int  up_attach(struct uart_dev_s *dev);
+static void up_detach(struct uart_dev_s *dev);
+static int  up_interrupt(int irq, void *context, void *arg);
+static int  up_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int  up_receive(struct uart_dev_s *dev, uint32_t *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+static void up_send(struct uart_dev_s *dev, int ch);
+static void up_txint(struct uart_dev_s *dev, bool enable);
+static bool up_txready(struct uart_dev_s *dev);
+static bool up_txempty(struct uart_dev_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct uart_ops_s g_uart_ops =
+{
+  .setup          = up_setup,
+  .shutdown       = up_shutdown,
+  .attach         = up_attach,
+  .detach         = up_detach,
+  .ioctl          = up_ioctl,
+  .receive        = up_receive,
+  .rxint          = up_rxint,
+  .rxavailable    = up_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = up_send,
+  .txint          = up_txint,
+  .txready        = up_txready,
+  .txempty        = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_S698PM_UART1
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART2
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART3
+static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART4
+static char g_uart3rxbuffer[CONFIG_UART4_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART4_TXBUFSIZE];
+#endif
+
+/* This describes the state of the S698PM UART1 port. */
+
+#ifdef CONFIG_S698PM_UART1
+static struct up_dev_s g_uart1priv =
+{
+  .uartbase  = S698PM_UART1_BASE,
+  .baud      = CONFIG_UART1_BAUD,
+  .irq       = S698PM_IRQ_UART_1_RX_TX,
+  .parity    = CONFIG_UART1_PARITY,
+  .bits      = CONFIG_UART1_BITS,
+  .stopbits2 = CONFIG_UART1_2STOP,
+};
+
+static uart_dev_t g_uart1port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART1_RXBUFSIZE,
+    .buffer  = g_uart1rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART1_TXBUFSIZE,
+    .buffer  = g_uart1txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart1priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART2 port. */
+
+#ifdef CONFIG_S698PM_UART2
+static struct up_dev_s g_uart2priv =
+{
+  .uartbase  = S698PM_UART2_BASE,
+  .baud      = CONFIG_UART2_BAUD,
+  .irq       = S698PM_IRQ_UART_2_RX_TX,
+  .parity    = CONFIG_UART2_PARITY,
+  .bits      = CONFIG_UART2_BITS,
+  .stopbits2 = CONFIG_UART2_2STOP,
+};
+
+static uart_dev_t g_uart2port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART2_RXBUFSIZE,
+    .buffer  = g_uart2rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART2_TXBUFSIZE,
+    .buffer  = g_uart2txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart2priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART3 port. */
+
+#ifdef CONFIG_S698PM_UART3
+static struct up_dev_s g_uart3priv =
+{
+  .uartbase  = S698PM_UART3_BASE,
+  .baud      = CONFIG_UART3_BAUD,
+  .irq       = S698PM_IRQ_UART_3_RX_TX,
+  .parity    = CONFIG_UART3_PARITY,
+  .bits      = CONFIG_UART3_BITS,
+  .stopbits2 = CONFIG_UART3_2STOP,
+};
+
+static uart_dev_t g_uart3port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART3_RXBUFSIZE,
+    .buffer  = g_uart3rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART3_TXBUFSIZE,
+    .buffer  = g_uart3txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart3priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART4 port. */
+
+#ifdef CONFIG_S698PM_UART4
+static struct up_dev_s g_uart4priv =
+{
+  .uartbase  = S698PM_UART4_BASE,
+  .baud      = CONFIG_UART4_BAUD,
+  .irq       = S698PM_IRQ_UART_4_RX_TX,
+  .parity    = CONFIG_UART4_PARITY,
+  .bits      = CONFIG_UART4_BITS,
+  .stopbits2 = CONFIG_UART4_2STOP,
+};
+
+static uart_dev_t g_uart4port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART4_RXBUFSIZE,
+    .buffer  = g_uart4rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART4_TXBUFSIZE,
+    .buffer  = g_uart4txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart4priv,
+};
+#endif
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_serialin
+ ****************************************************************************/
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset)
+{
+  return getreg32(priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_serialout
+ ****************************************************************************/
+
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value)
+{
+  putreg32(value, priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_setuartint
+ ****************************************************************************/
+
+static inline void up_setuartint(struct up_dev_s *priv)
+{
+  uint8_t regval;
+
+  regval   = up_serialin(priv, S698PM_UART_CTRLREG_OFFSET);
+  regval  &= ~MSK_UART_ALLINTS;
+  regval  |= priv->im;
+  up_serialout(priv, S698PM_UART_CTRLREG_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: up_restoreuartint
+ ****************************************************************************/
+
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  /* Re-enable/re-disable interrupts corresponding to the state of bits
+   * in im
+   */
+
+  flags = spin_lock_irqsave(&priv->lock);
+  priv->im  &= ~MSK_UART_ALLINTS;
+  priv->im  |= im;
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&priv->lock);
+  if (im)
+    {
+      *im = priv->im;
+    }
+
+  /* Disable all interrupts */
+
+  DISABLE_RX(priv->im);
+  DISABLE_TX(priv->im);
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_setup
+ *
+ * Description:
+ *   Configure the UART baud, bits, parity, etc. This method is called the
+ *   first time that the serial port is opened.
+ *
+ ****************************************************************************/
+
+static int up_setup(struct uart_dev_s *dev)
+{
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Configure the UART as an RS-232 UART */
+
+  s698pm_uartconfigure(priv->uartbase, priv->baud, priv->parity,
+                        priv->bits, priv->stopbits2);
+#endif
+
+#ifdef CONFIG_ARCH_IRQPRIO
+  /* Set up the interrupt priority */
+
+  up_prioritize_irq(priv->irq, priv->irqprio);
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_shutdown
+ *
+ * Description:
+ *   Disable the UART.  This method is called when the serial
+ *   port is closed
+ *
+ ****************************************************************************/
+
+static void up_shutdown(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Reset hardware and disable Rx and Tx */
+
+  s698pm_uartreset(priv->uartbase);
+}
+
+/****************************************************************************
+ * Name: up_attach
+ *
+ * Description:
+ *   Configure the UART to operation in interrupt driven mode. This method is
+ *   called when the serial port is opened.  Normally, this is just after the
+ *   the setup() method is called, however, the serial console may operate in
+ *   a non-interrupt driven mode during the boot phase.
+ *
+ *   RX and TX interrupts are not enabled by the attach method (unless the
+ *   hardware supports multiple levels of interrupt enabling).  The RX and TX
+ *   interrupts are not enabled until the txint() and rxint() methods are
+ *   called.
+ *
+ ****************************************************************************/
+
+static int up_attach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  int ret;
+
+  /* Attach and enable the IRQ */
+
+  ret = irq_attach(priv->irq, up_interrupt, dev);
+  if (ret == OK)
+    {
+      /* Set up to uart interrupts on the current CPU */
+
+       (void)s698pm_setup_irq(0, priv->irq, 0);
+
+      /* Enable the interrupt (RX and TX interrupts are still disabled
+       * in the USART
+       */
+
+       up_enable_irq(priv->irq);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_detach
+ *
+ * Description:
+ *   Detach UART interrupts.  This method is called when the serial port is
+ *   closed normally just before the shutdown method is called. The exception
+ *   is the serial console which is never shutdown.
+ *
+ ****************************************************************************/
+
+static void up_detach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Detach from the interrupt */
+
+  irq_detach(priv->irq);
+}
+
+/****************************************************************************
+ * Name: up_interrupt
+ *
+ * Description:
+ *   This is the UART interrupt handler.  It will be invoked when an
+ *   interrupt received on the 'irq'  It should call uart_transmitchars or
+ *   uart_receivechar to perform the appropriate data transfers.  The
+ *   interrupt handling logic must be able to map the 'irq' number into the
+ *   approprite uart_dev_s structure in order to call these functions.
+ *
+ ****************************************************************************/
+
+static int up_interrupt(int irq, void *context, void *arg)
+{
+  struct uart_dev_s *dev = (struct uart_dev_s *)arg;
+  struct up_dev_s   *priv;
+  uint32_t           mis;
+  int                passes;
+  bool               handled;
+
+  DEBUGASSERT(dev != NULL && dev->priv != NULL);
+  priv = (struct up_dev_s *)dev->priv;
+
+  /* Loop until there are no characters to be transferred or,
+   * until we have been looping for a long time.
+   */
+
+  handled = true;
+  for (passes = 0; passes < 256 && handled; passes++)
+    {
+      handled = false;
+
+      /* Get the masked UART status and clear the pending interrupts. */
+
+       mis = up_serialin(priv, S698PM_UART_STATREG_OFFSET);
+
+      /* Handle incoming, receive bytes */
+
+      if ((mis & UART_STA_DR) != 0)
+        {
+      /* Rx buffer not empty ... process incoming bytes */
+
+           uart_recvchars(dev);
+           handled = true;
+        }
+
+      /* Handle outgoing, transmit bytes */
+
+      if ((mis & UART_STA_TF) != UART_STA_TF)
+        {
+      /* Tx FIFO not full ... process outgoing bytes */
+
+      /* if (dev->xmit.head != dev->xmit.tail)
+       * {
+       */
+
+           uart_xmitchars(dev);
+           handled = true;
+
+      /* } */

Review Comment:
   Please remove!



##########
arch/sparc/src/s698pm/s698pm-serial.c:
##########
@@ -0,0 +1,1037 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/s698pm-serial.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+#  include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <nuttx/spinlock.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "s698pm-config.h"
+#include "chip.h"
+#include "s698pm-uart.h"
+#include "s698pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If we are not using the serial driver for the console, then we still must
+ * provide some minimal implementation of up_putc.
+ */
+
+#ifdef USE_SERIALDRIVER
+
+/* Which UART with be tty0/console and which tty1?  The console will always
+ * be ttyS0.  If there is no console then will use the lowest numbered UART.
+ */
+
+/* First pick the console and ttys0.  This could be any of UART1-4 */
+
+#if defined(CONFIG_UART1_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart1port /* UART1 is console */
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart2port /* UART2 is console */
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart3port /* UART3 is console */
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#elif defined(CONFIG_UART4_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart4port /* UART4 is console */
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#else
+#  undef CONSOLE_DEV                        /* No console */
+#  if defined(CONFIG_S698PM_UART1)
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART2)
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART3)
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART4)
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#  endif
+#endif
+
+/* Pick ttys1.  This could be any of UART1-4 excluding the console UART. */
+
+#if defined(CONFIG_S698PM_UART1) && !defined(UART1_ASSIGNED)
+#  define TTYS1_DEV           g_uart1port /* UART1 is ttyS1 */
+#  define UART1_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS1_DEV           g_uart2port /* UART2 is ttyS1 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS1_DEV           g_uart3port /* UART3 is ttyS1 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS1_DEV           g_uart4port /* UART4 is ttyS1 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys2.  This could be one of UART2-4. It can't be UART1 because that
+ * was either assigned as ttyS0 or ttys1.  One of UART 1-4 could also be the
+ * console.
+ */
+
+#if defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS2_DEV           g_uart2port /* UART2 is ttyS2 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS2_DEV           g_uart3port /* UART3 is ttyS2 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS2_DEV           g_uart4port /* UART4 is ttyS2 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys3. This could be one of UART3-4. It can't be UART1-2 because
+ * those have already been assigned to ttsyS0, 1, or 2.  One of
+ * UART 2-4 could also be the console.
+ */
+
+#if defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS3_DEV           g_uart3port /* UART3 is ttyS3 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS3_DEV           g_uart4port /* UART4 is ttyS3 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Common initialization logic will not not know that the all of the UARTs
+ * have been disabled.  So, as a result, we may still have to provide
+ * stub implementations of up_earlyserialinit(), up_serialinit(), and
+ * up_putc().
+ */
+
+#ifdef HAVE_UART_DEVICE
+
+/* These values describe the set of enabled interrupts */
+
+#define RX_ENABLED(im)    (((im) & MSK_UART_ENABLE_RX) != 0)
+#define TX_ENABLED(im)    (((im) & MSK_UART_ENABLE_TX) != 0)
+
+#define ENABLE_RX(im)     do { (im) |= MSK_UART_ENABLE_RX; } while (0)
+#define ENABLE_TX(im)     do { (im) |= MSK_UART_ENABLE_TX; } while (0)
+
+#define DISABLE_RX(im)    do { (im) &= ~MSK_UART_ENABLE_RX; } while (0)
+#define DISABLE_TX(im)    do { (im) &= ~MSK_UART_ENABLE_TX; } while (0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct up_dev_s
+{
+  uintptr_t uartbase;  /* Base address of UART registers */
+  uint32_t  baud;      /* Configured baud */
+  uint8_t   irq;       /* IRQ associated with this UART (for attachment) */
+  uint8_t   im;        /* Interrupt mask state */
+  uint8_t   parity;    /* 0=none, 1=odd, 2=even */
+  uint8_t   bits;      /* Number of bits (5, 6, 7 or 8) */
+  bool      stopbits2; /* true: Configure with 2 stop bits instead of 1 */
+  spinlock_t lock;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers */
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset);
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value);
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im);
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im);
+
+/* Serial driver methods */
+
+static int  up_setup(struct uart_dev_s *dev);
+static void up_shutdown(struct uart_dev_s *dev);
+static int  up_attach(struct uart_dev_s *dev);
+static void up_detach(struct uart_dev_s *dev);
+static int  up_interrupt(int irq, void *context, void *arg);
+static int  up_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int  up_receive(struct uart_dev_s *dev, uint32_t *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+static void up_send(struct uart_dev_s *dev, int ch);
+static void up_txint(struct uart_dev_s *dev, bool enable);
+static bool up_txready(struct uart_dev_s *dev);
+static bool up_txempty(struct uart_dev_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct uart_ops_s g_uart_ops =
+{
+  .setup          = up_setup,
+  .shutdown       = up_shutdown,
+  .attach         = up_attach,
+  .detach         = up_detach,
+  .ioctl          = up_ioctl,
+  .receive        = up_receive,
+  .rxint          = up_rxint,
+  .rxavailable    = up_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = up_send,
+  .txint          = up_txint,
+  .txready        = up_txready,
+  .txempty        = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_S698PM_UART1
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART2
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART3
+static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART4
+static char g_uart3rxbuffer[CONFIG_UART4_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART4_TXBUFSIZE];
+#endif
+
+/* This describes the state of the S698PM UART1 port. */
+
+#ifdef CONFIG_S698PM_UART1
+static struct up_dev_s g_uart1priv =
+{
+  .uartbase  = S698PM_UART1_BASE,
+  .baud      = CONFIG_UART1_BAUD,
+  .irq       = S698PM_IRQ_UART_1_RX_TX,
+  .parity    = CONFIG_UART1_PARITY,
+  .bits      = CONFIG_UART1_BITS,
+  .stopbits2 = CONFIG_UART1_2STOP,
+};
+
+static uart_dev_t g_uart1port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART1_RXBUFSIZE,
+    .buffer  = g_uart1rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART1_TXBUFSIZE,
+    .buffer  = g_uart1txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart1priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART2 port. */
+
+#ifdef CONFIG_S698PM_UART2
+static struct up_dev_s g_uart2priv =
+{
+  .uartbase  = S698PM_UART2_BASE,
+  .baud      = CONFIG_UART2_BAUD,
+  .irq       = S698PM_IRQ_UART_2_RX_TX,
+  .parity    = CONFIG_UART2_PARITY,
+  .bits      = CONFIG_UART2_BITS,
+  .stopbits2 = CONFIG_UART2_2STOP,
+};
+
+static uart_dev_t g_uart2port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART2_RXBUFSIZE,
+    .buffer  = g_uart2rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART2_TXBUFSIZE,
+    .buffer  = g_uart2txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart2priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART3 port. */
+
+#ifdef CONFIG_S698PM_UART3
+static struct up_dev_s g_uart3priv =
+{
+  .uartbase  = S698PM_UART3_BASE,
+  .baud      = CONFIG_UART3_BAUD,
+  .irq       = S698PM_IRQ_UART_3_RX_TX,
+  .parity    = CONFIG_UART3_PARITY,
+  .bits      = CONFIG_UART3_BITS,
+  .stopbits2 = CONFIG_UART3_2STOP,
+};
+
+static uart_dev_t g_uart3port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART3_RXBUFSIZE,
+    .buffer  = g_uart3rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART3_TXBUFSIZE,
+    .buffer  = g_uart3txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart3priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART4 port. */
+
+#ifdef CONFIG_S698PM_UART4
+static struct up_dev_s g_uart4priv =
+{
+  .uartbase  = S698PM_UART4_BASE,
+  .baud      = CONFIG_UART4_BAUD,
+  .irq       = S698PM_IRQ_UART_4_RX_TX,
+  .parity    = CONFIG_UART4_PARITY,
+  .bits      = CONFIG_UART4_BITS,
+  .stopbits2 = CONFIG_UART4_2STOP,
+};
+
+static uart_dev_t g_uart4port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART4_RXBUFSIZE,
+    .buffer  = g_uart4rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART4_TXBUFSIZE,
+    .buffer  = g_uart4txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart4priv,
+};
+#endif
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_serialin
+ ****************************************************************************/
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset)
+{
+  return getreg32(priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_serialout
+ ****************************************************************************/
+
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value)
+{
+  putreg32(value, priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_setuartint
+ ****************************************************************************/
+
+static inline void up_setuartint(struct up_dev_s *priv)
+{
+  uint8_t regval;
+
+  regval   = up_serialin(priv, S698PM_UART_CTRLREG_OFFSET);
+  regval  &= ~MSK_UART_ALLINTS;
+  regval  |= priv->im;
+  up_serialout(priv, S698PM_UART_CTRLREG_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: up_restoreuartint
+ ****************************************************************************/
+
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  /* Re-enable/re-disable interrupts corresponding to the state of bits
+   * in im
+   */
+
+  flags = spin_lock_irqsave(&priv->lock);
+  priv->im  &= ~MSK_UART_ALLINTS;
+  priv->im  |= im;
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&priv->lock);
+  if (im)
+    {
+      *im = priv->im;
+    }
+
+  /* Disable all interrupts */
+
+  DISABLE_RX(priv->im);
+  DISABLE_TX(priv->im);
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_setup
+ *
+ * Description:
+ *   Configure the UART baud, bits, parity, etc. This method is called the
+ *   first time that the serial port is opened.
+ *
+ ****************************************************************************/
+
+static int up_setup(struct uart_dev_s *dev)
+{
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Configure the UART as an RS-232 UART */
+
+  s698pm_uartconfigure(priv->uartbase, priv->baud, priv->parity,
+                        priv->bits, priv->stopbits2);
+#endif
+
+#ifdef CONFIG_ARCH_IRQPRIO
+  /* Set up the interrupt priority */
+
+  up_prioritize_irq(priv->irq, priv->irqprio);
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_shutdown
+ *
+ * Description:
+ *   Disable the UART.  This method is called when the serial
+ *   port is closed
+ *
+ ****************************************************************************/
+
+static void up_shutdown(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Reset hardware and disable Rx and Tx */
+
+  s698pm_uartreset(priv->uartbase);
+}
+
+/****************************************************************************
+ * Name: up_attach
+ *
+ * Description:
+ *   Configure the UART to operation in interrupt driven mode. This method is
+ *   called when the serial port is opened.  Normally, this is just after the
+ *   the setup() method is called, however, the serial console may operate in
+ *   a non-interrupt driven mode during the boot phase.
+ *
+ *   RX and TX interrupts are not enabled by the attach method (unless the
+ *   hardware supports multiple levels of interrupt enabling).  The RX and TX
+ *   interrupts are not enabled until the txint() and rxint() methods are
+ *   called.
+ *
+ ****************************************************************************/
+
+static int up_attach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  int ret;
+
+  /* Attach and enable the IRQ */
+
+  ret = irq_attach(priv->irq, up_interrupt, dev);
+  if (ret == OK)
+    {
+      /* Set up to uart interrupts on the current CPU */
+
+       (void)s698pm_setup_irq(0, priv->irq, 0);
+
+      /* Enable the interrupt (RX and TX interrupts are still disabled
+       * in the USART
+       */
+
+       up_enable_irq(priv->irq);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_detach
+ *
+ * Description:
+ *   Detach UART interrupts.  This method is called when the serial port is
+ *   closed normally just before the shutdown method is called. The exception
+ *   is the serial console which is never shutdown.
+ *
+ ****************************************************************************/
+
+static void up_detach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Detach from the interrupt */
+
+  irq_detach(priv->irq);
+}
+
+/****************************************************************************
+ * Name: up_interrupt
+ *
+ * Description:
+ *   This is the UART interrupt handler.  It will be invoked when an
+ *   interrupt received on the 'irq'  It should call uart_transmitchars or
+ *   uart_receivechar to perform the appropriate data transfers.  The
+ *   interrupt handling logic must be able to map the 'irq' number into the
+ *   approprite uart_dev_s structure in order to call these functions.
+ *
+ ****************************************************************************/
+
+static int up_interrupt(int irq, void *context, void *arg)
+{
+  struct uart_dev_s *dev = (struct uart_dev_s *)arg;
+  struct up_dev_s   *priv;
+  uint32_t           mis;
+  int                passes;
+  bool               handled;
+
+  DEBUGASSERT(dev != NULL && dev->priv != NULL);
+  priv = (struct up_dev_s *)dev->priv;
+
+  /* Loop until there are no characters to be transferred or,
+   * until we have been looping for a long time.
+   */
+
+  handled = true;
+  for (passes = 0; passes < 256 && handled; passes++)
+    {
+      handled = false;
+
+      /* Get the masked UART status and clear the pending interrupts. */
+
+       mis = up_serialin(priv, S698PM_UART_STATREG_OFFSET);
+
+      /* Handle incoming, receive bytes */
+
+      if ((mis & UART_STA_DR) != 0)
+        {
+      /* Rx buffer not empty ... process incoming bytes */

Review Comment:
   Please align



##########
arch/sparc/src/s698pm/s698pm-irq.c:
##########
@@ -0,0 +1,533 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/s698pm-irq.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+
+#include <arch/irq.h>
+
+#include "up_internal.h"
+#include "s698pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+
+#if defined(CONFIG_SMP)
+#  define INTSTACK_ALLOC (CONFIG_SMP_NCPUS * INTSTACK_SIZE)
+#else
+#  define INTSTACK_ALLOC (INTSTACK_SIZE)
+#endif
+
+#endif
+
+/* IRQ to CPU and CPU interrupts mapping:
+ *
+ * Encoding: CCCIIIII
+ *  C: CPU that enabled the interrupt (0 ~ 3).
+ *  I: Associated CPU interrupt (0 ~ 31).
+ */
+
+#define IRQ_UNMAPPED      0xff
+#define IRQ_GETCPU(m)     (((m) & 0xe0) >> 0x05)
+#define IRQ_GETCPUINT(m)  ((m) & 0x1f)
+#define IRQ_MKMAP(c, i)   (((c) << 0x05) | (i))
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+static volatile uint8_t g_irqmap[NR_IRQS];
+
+#if CONFIG_ARCH_INTERRUPTSTACK > 7
+/* In the SMP configuration, we will need custom interrupt stacks.
+ * These definitions provide the aligned stack allocations.
+ */
+
+static uint64_t g_intstack_alloc[INTSTACK_ALLOC >> 3];
+
+/* These definitions provide the "top" of the push-down stacks. */
+
+uintptr_t g_cpu_intstack_top[CONFIG_SMP_NCPUS] =
+{
+  (uintptr_t)g_intstack_alloc + INTSTACK_SIZE,
+#if defined(CONFIG_SMP)
+
+#if CONFIG_SMP_NCPUS > 1
+  (uintptr_t)g_intstack_alloc + (2 * INTSTACK_SIZE),
+#if CONFIG_SMP_NCPUS > 2
+  (uintptr_t)g_intstack_alloc + (3 * INTSTACK_SIZE),
+#if CONFIG_SMP_NCPUS > 3
+  (uintptr_t)g_intstack_alloc + (4 * INTSTACK_SIZE),
+#endif /* CONFIG_SMP_NCPUS > 3 */
+#endif /* CONFIG_SMP_NCPUS > 2 */
+#endif /* CONFIG_SMP_NCPUS > 1 */
+
+#endif /* defined(CONFIG_SMP) */
+};
+#endif /* if CONFIG_ARCH_INTERRUPTSTACK > 7 */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_IRQPRIO
+static int up_prioritize_irq(int irq, int priority);
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_irqinitialize
+ ****************************************************************************/
+
+void up_irqinitialize(void)
+{
+  int irq = 0;
+
+  for (irq = 0; irq < NR_IRQS; irq++)
+    {
+      g_irqmap[irq] = IRQ_UNMAPPED;
+    }
+
+  /* Initialize CPU interrupts */
+
+  s698pm_cpuint_initialize();
+
+  /* Set interrupts priority */
+
+  for (irq = 0x11; irq < 0x20; irq++)

Review Comment:
   ```suggestion
     for (irq = S698PM_IRQ_FIRST_INT; irq =< S698PM_IRQ_LAST_INT; irq++)
   ```



##########
arch/sparc/src/s698pm/s698pm-serial.c:
##########
@@ -0,0 +1,1037 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/s698pm-serial.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+#  include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <nuttx/spinlock.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "s698pm-config.h"
+#include "chip.h"
+#include "s698pm-uart.h"
+#include "s698pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If we are not using the serial driver for the console, then we still must
+ * provide some minimal implementation of up_putc.
+ */
+
+#ifdef USE_SERIALDRIVER
+
+/* Which UART with be tty0/console and which tty1?  The console will always
+ * be ttyS0.  If there is no console then will use the lowest numbered UART.
+ */
+
+/* First pick the console and ttys0.  This could be any of UART1-4 */
+
+#if defined(CONFIG_UART1_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart1port /* UART1 is console */
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart2port /* UART2 is console */
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart3port /* UART3 is console */
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#elif defined(CONFIG_UART4_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart4port /* UART4 is console */
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#else
+#  undef CONSOLE_DEV                        /* No console */
+#  if defined(CONFIG_S698PM_UART1)
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART2)
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART3)
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART4)
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#  endif
+#endif
+
+/* Pick ttys1.  This could be any of UART1-4 excluding the console UART. */
+
+#if defined(CONFIG_S698PM_UART1) && !defined(UART1_ASSIGNED)
+#  define TTYS1_DEV           g_uart1port /* UART1 is ttyS1 */
+#  define UART1_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS1_DEV           g_uart2port /* UART2 is ttyS1 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS1_DEV           g_uart3port /* UART3 is ttyS1 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS1_DEV           g_uart4port /* UART4 is ttyS1 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys2.  This could be one of UART2-4. It can't be UART1 because that
+ * was either assigned as ttyS0 or ttys1.  One of UART 1-4 could also be the
+ * console.
+ */
+
+#if defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS2_DEV           g_uart2port /* UART2 is ttyS2 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS2_DEV           g_uart3port /* UART3 is ttyS2 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS2_DEV           g_uart4port /* UART4 is ttyS2 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys3. This could be one of UART3-4. It can't be UART1-2 because
+ * those have already been assigned to ttsyS0, 1, or 2.  One of
+ * UART 2-4 could also be the console.
+ */
+
+#if defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS3_DEV           g_uart3port /* UART3 is ttyS3 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS3_DEV           g_uart4port /* UART4 is ttyS3 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Common initialization logic will not not know that the all of the UARTs
+ * have been disabled.  So, as a result, we may still have to provide
+ * stub implementations of up_earlyserialinit(), up_serialinit(), and
+ * up_putc().
+ */
+
+#ifdef HAVE_UART_DEVICE
+
+/* These values describe the set of enabled interrupts */
+
+#define RX_ENABLED(im)    (((im) & MSK_UART_ENABLE_RX) != 0)
+#define TX_ENABLED(im)    (((im) & MSK_UART_ENABLE_TX) != 0)
+
+#define ENABLE_RX(im)     do { (im) |= MSK_UART_ENABLE_RX; } while (0)
+#define ENABLE_TX(im)     do { (im) |= MSK_UART_ENABLE_TX; } while (0)
+
+#define DISABLE_RX(im)    do { (im) &= ~MSK_UART_ENABLE_RX; } while (0)
+#define DISABLE_TX(im)    do { (im) &= ~MSK_UART_ENABLE_TX; } while (0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct up_dev_s
+{
+  uintptr_t uartbase;  /* Base address of UART registers */
+  uint32_t  baud;      /* Configured baud */
+  uint8_t   irq;       /* IRQ associated with this UART (for attachment) */
+  uint8_t   im;        /* Interrupt mask state */
+  uint8_t   parity;    /* 0=none, 1=odd, 2=even */
+  uint8_t   bits;      /* Number of bits (5, 6, 7 or 8) */
+  bool      stopbits2; /* true: Configure with 2 stop bits instead of 1 */
+  spinlock_t lock;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers */
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset);
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value);
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im);
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im);
+
+/* Serial driver methods */
+
+static int  up_setup(struct uart_dev_s *dev);
+static void up_shutdown(struct uart_dev_s *dev);
+static int  up_attach(struct uart_dev_s *dev);
+static void up_detach(struct uart_dev_s *dev);
+static int  up_interrupt(int irq, void *context, void *arg);
+static int  up_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int  up_receive(struct uart_dev_s *dev, uint32_t *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+static void up_send(struct uart_dev_s *dev, int ch);
+static void up_txint(struct uart_dev_s *dev, bool enable);
+static bool up_txready(struct uart_dev_s *dev);
+static bool up_txempty(struct uart_dev_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct uart_ops_s g_uart_ops =
+{
+  .setup          = up_setup,
+  .shutdown       = up_shutdown,
+  .attach         = up_attach,
+  .detach         = up_detach,
+  .ioctl          = up_ioctl,
+  .receive        = up_receive,
+  .rxint          = up_rxint,
+  .rxavailable    = up_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = up_send,
+  .txint          = up_txint,
+  .txready        = up_txready,
+  .txempty        = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_S698PM_UART1
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART2
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART3
+static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART4
+static char g_uart3rxbuffer[CONFIG_UART4_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART4_TXBUFSIZE];
+#endif
+
+/* This describes the state of the S698PM UART1 port. */
+
+#ifdef CONFIG_S698PM_UART1
+static struct up_dev_s g_uart1priv =
+{
+  .uartbase  = S698PM_UART1_BASE,
+  .baud      = CONFIG_UART1_BAUD,
+  .irq       = S698PM_IRQ_UART_1_RX_TX,
+  .parity    = CONFIG_UART1_PARITY,
+  .bits      = CONFIG_UART1_BITS,
+  .stopbits2 = CONFIG_UART1_2STOP,
+};
+
+static uart_dev_t g_uart1port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART1_RXBUFSIZE,
+    .buffer  = g_uart1rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART1_TXBUFSIZE,
+    .buffer  = g_uart1txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart1priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART2 port. */
+
+#ifdef CONFIG_S698PM_UART2
+static struct up_dev_s g_uart2priv =
+{
+  .uartbase  = S698PM_UART2_BASE,
+  .baud      = CONFIG_UART2_BAUD,
+  .irq       = S698PM_IRQ_UART_2_RX_TX,
+  .parity    = CONFIG_UART2_PARITY,
+  .bits      = CONFIG_UART2_BITS,
+  .stopbits2 = CONFIG_UART2_2STOP,
+};
+
+static uart_dev_t g_uart2port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART2_RXBUFSIZE,
+    .buffer  = g_uart2rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART2_TXBUFSIZE,
+    .buffer  = g_uart2txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart2priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART3 port. */
+
+#ifdef CONFIG_S698PM_UART3
+static struct up_dev_s g_uart3priv =
+{
+  .uartbase  = S698PM_UART3_BASE,
+  .baud      = CONFIG_UART3_BAUD,
+  .irq       = S698PM_IRQ_UART_3_RX_TX,
+  .parity    = CONFIG_UART3_PARITY,
+  .bits      = CONFIG_UART3_BITS,
+  .stopbits2 = CONFIG_UART3_2STOP,
+};
+
+static uart_dev_t g_uart3port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART3_RXBUFSIZE,
+    .buffer  = g_uart3rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART3_TXBUFSIZE,
+    .buffer  = g_uart3txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart3priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART4 port. */
+
+#ifdef CONFIG_S698PM_UART4
+static struct up_dev_s g_uart4priv =
+{
+  .uartbase  = S698PM_UART4_BASE,
+  .baud      = CONFIG_UART4_BAUD,
+  .irq       = S698PM_IRQ_UART_4_RX_TX,
+  .parity    = CONFIG_UART4_PARITY,
+  .bits      = CONFIG_UART4_BITS,
+  .stopbits2 = CONFIG_UART4_2STOP,
+};
+
+static uart_dev_t g_uart4port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART4_RXBUFSIZE,
+    .buffer  = g_uart4rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART4_TXBUFSIZE,
+    .buffer  = g_uart4txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart4priv,
+};
+#endif
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_serialin
+ ****************************************************************************/
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset)
+{
+  return getreg32(priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_serialout
+ ****************************************************************************/
+
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value)
+{
+  putreg32(value, priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_setuartint
+ ****************************************************************************/
+
+static inline void up_setuartint(struct up_dev_s *priv)
+{
+  uint8_t regval;
+
+  regval   = up_serialin(priv, S698PM_UART_CTRLREG_OFFSET);
+  regval  &= ~MSK_UART_ALLINTS;
+  regval  |= priv->im;
+  up_serialout(priv, S698PM_UART_CTRLREG_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: up_restoreuartint
+ ****************************************************************************/
+
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  /* Re-enable/re-disable interrupts corresponding to the state of bits
+   * in im
+   */
+
+  flags = spin_lock_irqsave(&priv->lock);
+  priv->im  &= ~MSK_UART_ALLINTS;
+  priv->im  |= im;
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&priv->lock);
+  if (im)
+    {
+      *im = priv->im;
+    }
+
+  /* Disable all interrupts */
+
+  DISABLE_RX(priv->im);
+  DISABLE_TX(priv->im);
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_setup
+ *
+ * Description:
+ *   Configure the UART baud, bits, parity, etc. This method is called the
+ *   first time that the serial port is opened.
+ *
+ ****************************************************************************/
+
+static int up_setup(struct uart_dev_s *dev)
+{
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Configure the UART as an RS-232 UART */
+
+  s698pm_uartconfigure(priv->uartbase, priv->baud, priv->parity,
+                        priv->bits, priv->stopbits2);
+#endif
+
+#ifdef CONFIG_ARCH_IRQPRIO
+  /* Set up the interrupt priority */
+
+  up_prioritize_irq(priv->irq, priv->irqprio);
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_shutdown
+ *
+ * Description:
+ *   Disable the UART.  This method is called when the serial
+ *   port is closed
+ *
+ ****************************************************************************/
+
+static void up_shutdown(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Reset hardware and disable Rx and Tx */
+
+  s698pm_uartreset(priv->uartbase);
+}
+
+/****************************************************************************
+ * Name: up_attach
+ *
+ * Description:
+ *   Configure the UART to operation in interrupt driven mode. This method is
+ *   called when the serial port is opened.  Normally, this is just after the
+ *   the setup() method is called, however, the serial console may operate in
+ *   a non-interrupt driven mode during the boot phase.
+ *
+ *   RX and TX interrupts are not enabled by the attach method (unless the
+ *   hardware supports multiple levels of interrupt enabling).  The RX and TX
+ *   interrupts are not enabled until the txint() and rxint() methods are
+ *   called.
+ *
+ ****************************************************************************/
+
+static int up_attach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  int ret;
+
+  /* Attach and enable the IRQ */
+
+  ret = irq_attach(priv->irq, up_interrupt, dev);
+  if (ret == OK)
+    {
+      /* Set up to uart interrupts on the current CPU */
+
+       (void)s698pm_setup_irq(0, priv->irq, 0);
+
+      /* Enable the interrupt (RX and TX interrupts are still disabled
+       * in the USART
+       */
+
+       up_enable_irq(priv->irq);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_detach
+ *
+ * Description:
+ *   Detach UART interrupts.  This method is called when the serial port is
+ *   closed normally just before the shutdown method is called. The exception
+ *   is the serial console which is never shutdown.
+ *
+ ****************************************************************************/
+
+static void up_detach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Detach from the interrupt */
+
+  irq_detach(priv->irq);
+}
+
+/****************************************************************************
+ * Name: up_interrupt
+ *
+ * Description:
+ *   This is the UART interrupt handler.  It will be invoked when an
+ *   interrupt received on the 'irq'  It should call uart_transmitchars or
+ *   uart_receivechar to perform the appropriate data transfers.  The
+ *   interrupt handling logic must be able to map the 'irq' number into the
+ *   approprite uart_dev_s structure in order to call these functions.
+ *
+ ****************************************************************************/
+
+static int up_interrupt(int irq, void *context, void *arg)
+{
+  struct uart_dev_s *dev = (struct uart_dev_s *)arg;
+  struct up_dev_s   *priv;
+  uint32_t           mis;
+  int                passes;
+  bool               handled;
+
+  DEBUGASSERT(dev != NULL && dev->priv != NULL);
+  priv = (struct up_dev_s *)dev->priv;
+
+  /* Loop until there are no characters to be transferred or,
+   * until we have been looping for a long time.
+   */
+
+  handled = true;
+  for (passes = 0; passes < 256 && handled; passes++)
+    {
+      handled = false;
+
+      /* Get the masked UART status and clear the pending interrupts. */
+
+       mis = up_serialin(priv, S698PM_UART_STATREG_OFFSET);
+
+      /* Handle incoming, receive bytes */
+
+      if ((mis & UART_STA_DR) != 0)
+        {
+      /* Rx buffer not empty ... process incoming bytes */
+
+           uart_recvchars(dev);
+           handled = true;
+        }
+
+      /* Handle outgoing, transmit bytes */
+
+      if ((mis & UART_STA_TF) != UART_STA_TF)
+        {
+      /* Tx FIFO not full ... process outgoing bytes */
+
+      /* if (dev->xmit.head != dev->xmit.tail)
+       * {
+       */

Review Comment:
   Please remove!



##########
arch/sparc/src/s698pm/s698pm-serial.c:
##########
@@ -0,0 +1,1037 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/s698pm-serial.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+#  include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <nuttx/spinlock.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "s698pm-config.h"
+#include "chip.h"
+#include "s698pm-uart.h"
+#include "s698pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If we are not using the serial driver for the console, then we still must
+ * provide some minimal implementation of up_putc.
+ */
+
+#ifdef USE_SERIALDRIVER
+
+/* Which UART with be tty0/console and which tty1?  The console will always
+ * be ttyS0.  If there is no console then will use the lowest numbered UART.
+ */
+
+/* First pick the console and ttys0.  This could be any of UART1-4 */
+
+#if defined(CONFIG_UART1_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart1port /* UART1 is console */
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart2port /* UART2 is console */
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart3port /* UART3 is console */
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#elif defined(CONFIG_UART4_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart4port /* UART4 is console */
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#else
+#  undef CONSOLE_DEV                        /* No console */
+#  if defined(CONFIG_S698PM_UART1)
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART2)
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART3)
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART4)
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#  endif
+#endif
+
+/* Pick ttys1.  This could be any of UART1-4 excluding the console UART. */
+
+#if defined(CONFIG_S698PM_UART1) && !defined(UART1_ASSIGNED)
+#  define TTYS1_DEV           g_uart1port /* UART1 is ttyS1 */
+#  define UART1_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS1_DEV           g_uart2port /* UART2 is ttyS1 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS1_DEV           g_uart3port /* UART3 is ttyS1 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS1_DEV           g_uart4port /* UART4 is ttyS1 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys2.  This could be one of UART2-4. It can't be UART1 because that
+ * was either assigned as ttyS0 or ttys1.  One of UART 1-4 could also be the
+ * console.
+ */
+
+#if defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS2_DEV           g_uart2port /* UART2 is ttyS2 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS2_DEV           g_uart3port /* UART3 is ttyS2 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS2_DEV           g_uart4port /* UART4 is ttyS2 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys3. This could be one of UART3-4. It can't be UART1-2 because
+ * those have already been assigned to ttsyS0, 1, or 2.  One of
+ * UART 2-4 could also be the console.
+ */
+
+#if defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS3_DEV           g_uart3port /* UART3 is ttyS3 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS3_DEV           g_uart4port /* UART4 is ttyS3 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Common initialization logic will not not know that the all of the UARTs
+ * have been disabled.  So, as a result, we may still have to provide
+ * stub implementations of up_earlyserialinit(), up_serialinit(), and
+ * up_putc().
+ */
+
+#ifdef HAVE_UART_DEVICE
+
+/* These values describe the set of enabled interrupts */
+
+#define RX_ENABLED(im)    (((im) & MSK_UART_ENABLE_RX) != 0)
+#define TX_ENABLED(im)    (((im) & MSK_UART_ENABLE_TX) != 0)
+
+#define ENABLE_RX(im)     do { (im) |= MSK_UART_ENABLE_RX; } while (0)
+#define ENABLE_TX(im)     do { (im) |= MSK_UART_ENABLE_TX; } while (0)
+
+#define DISABLE_RX(im)    do { (im) &= ~MSK_UART_ENABLE_RX; } while (0)
+#define DISABLE_TX(im)    do { (im) &= ~MSK_UART_ENABLE_TX; } while (0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct up_dev_s
+{
+  uintptr_t uartbase;  /* Base address of UART registers */
+  uint32_t  baud;      /* Configured baud */
+  uint8_t   irq;       /* IRQ associated with this UART (for attachment) */
+  uint8_t   im;        /* Interrupt mask state */
+  uint8_t   parity;    /* 0=none, 1=odd, 2=even */
+  uint8_t   bits;      /* Number of bits (5, 6, 7 or 8) */
+  bool      stopbits2; /* true: Configure with 2 stop bits instead of 1 */
+  spinlock_t lock;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers */
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset);
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value);
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im);
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im);
+
+/* Serial driver methods */
+
+static int  up_setup(struct uart_dev_s *dev);
+static void up_shutdown(struct uart_dev_s *dev);
+static int  up_attach(struct uart_dev_s *dev);
+static void up_detach(struct uart_dev_s *dev);
+static int  up_interrupt(int irq, void *context, void *arg);
+static int  up_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int  up_receive(struct uart_dev_s *dev, uint32_t *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+static void up_send(struct uart_dev_s *dev, int ch);
+static void up_txint(struct uart_dev_s *dev, bool enable);
+static bool up_txready(struct uart_dev_s *dev);
+static bool up_txempty(struct uart_dev_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct uart_ops_s g_uart_ops =
+{
+  .setup          = up_setup,
+  .shutdown       = up_shutdown,
+  .attach         = up_attach,
+  .detach         = up_detach,
+  .ioctl          = up_ioctl,
+  .receive        = up_receive,
+  .rxint          = up_rxint,
+  .rxavailable    = up_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = up_send,
+  .txint          = up_txint,
+  .txready        = up_txready,
+  .txempty        = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_S698PM_UART1
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART2
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART3
+static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART4
+static char g_uart3rxbuffer[CONFIG_UART4_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART4_TXBUFSIZE];
+#endif
+
+/* This describes the state of the S698PM UART1 port. */
+
+#ifdef CONFIG_S698PM_UART1
+static struct up_dev_s g_uart1priv =
+{
+  .uartbase  = S698PM_UART1_BASE,
+  .baud      = CONFIG_UART1_BAUD,
+  .irq       = S698PM_IRQ_UART_1_RX_TX,
+  .parity    = CONFIG_UART1_PARITY,
+  .bits      = CONFIG_UART1_BITS,
+  .stopbits2 = CONFIG_UART1_2STOP,
+};
+
+static uart_dev_t g_uart1port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART1_RXBUFSIZE,
+    .buffer  = g_uart1rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART1_TXBUFSIZE,
+    .buffer  = g_uart1txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart1priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART2 port. */
+
+#ifdef CONFIG_S698PM_UART2
+static struct up_dev_s g_uart2priv =
+{
+  .uartbase  = S698PM_UART2_BASE,
+  .baud      = CONFIG_UART2_BAUD,
+  .irq       = S698PM_IRQ_UART_2_RX_TX,
+  .parity    = CONFIG_UART2_PARITY,
+  .bits      = CONFIG_UART2_BITS,
+  .stopbits2 = CONFIG_UART2_2STOP,
+};
+
+static uart_dev_t g_uart2port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART2_RXBUFSIZE,
+    .buffer  = g_uart2rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART2_TXBUFSIZE,
+    .buffer  = g_uart2txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart2priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART3 port. */
+
+#ifdef CONFIG_S698PM_UART3
+static struct up_dev_s g_uart3priv =
+{
+  .uartbase  = S698PM_UART3_BASE,
+  .baud      = CONFIG_UART3_BAUD,
+  .irq       = S698PM_IRQ_UART_3_RX_TX,
+  .parity    = CONFIG_UART3_PARITY,
+  .bits      = CONFIG_UART3_BITS,
+  .stopbits2 = CONFIG_UART3_2STOP,
+};
+
+static uart_dev_t g_uart3port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART3_RXBUFSIZE,
+    .buffer  = g_uart3rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART3_TXBUFSIZE,
+    .buffer  = g_uart3txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart3priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART4 port. */
+
+#ifdef CONFIG_S698PM_UART4
+static struct up_dev_s g_uart4priv =
+{
+  .uartbase  = S698PM_UART4_BASE,
+  .baud      = CONFIG_UART4_BAUD,
+  .irq       = S698PM_IRQ_UART_4_RX_TX,
+  .parity    = CONFIG_UART4_PARITY,
+  .bits      = CONFIG_UART4_BITS,
+  .stopbits2 = CONFIG_UART4_2STOP,
+};
+
+static uart_dev_t g_uart4port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART4_RXBUFSIZE,
+    .buffer  = g_uart4rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART4_TXBUFSIZE,
+    .buffer  = g_uart4txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart4priv,
+};
+#endif
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_serialin
+ ****************************************************************************/
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset)
+{
+  return getreg32(priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_serialout
+ ****************************************************************************/
+
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value)
+{
+  putreg32(value, priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_setuartint
+ ****************************************************************************/
+
+static inline void up_setuartint(struct up_dev_s *priv)
+{
+  uint8_t regval;
+
+  regval   = up_serialin(priv, S698PM_UART_CTRLREG_OFFSET);
+  regval  &= ~MSK_UART_ALLINTS;
+  regval  |= priv->im;
+  up_serialout(priv, S698PM_UART_CTRLREG_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: up_restoreuartint
+ ****************************************************************************/
+
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  /* Re-enable/re-disable interrupts corresponding to the state of bits
+   * in im
+   */
+
+  flags = spin_lock_irqsave(&priv->lock);
+  priv->im  &= ~MSK_UART_ALLINTS;
+  priv->im  |= im;
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&priv->lock);
+  if (im)
+    {
+      *im = priv->im;
+    }
+
+  /* Disable all interrupts */
+
+  DISABLE_RX(priv->im);
+  DISABLE_TX(priv->im);
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_setup
+ *
+ * Description:
+ *   Configure the UART baud, bits, parity, etc. This method is called the
+ *   first time that the serial port is opened.
+ *
+ ****************************************************************************/
+
+static int up_setup(struct uart_dev_s *dev)
+{
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Configure the UART as an RS-232 UART */
+
+  s698pm_uartconfigure(priv->uartbase, priv->baud, priv->parity,
+                        priv->bits, priv->stopbits2);
+#endif
+
+#ifdef CONFIG_ARCH_IRQPRIO
+  /* Set up the interrupt priority */
+
+  up_prioritize_irq(priv->irq, priv->irqprio);
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_shutdown
+ *
+ * Description:
+ *   Disable the UART.  This method is called when the serial
+ *   port is closed
+ *
+ ****************************************************************************/
+
+static void up_shutdown(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Reset hardware and disable Rx and Tx */
+
+  s698pm_uartreset(priv->uartbase);
+}
+
+/****************************************************************************
+ * Name: up_attach
+ *
+ * Description:
+ *   Configure the UART to operation in interrupt driven mode. This method is
+ *   called when the serial port is opened.  Normally, this is just after the
+ *   the setup() method is called, however, the serial console may operate in
+ *   a non-interrupt driven mode during the boot phase.
+ *
+ *   RX and TX interrupts are not enabled by the attach method (unless the
+ *   hardware supports multiple levels of interrupt enabling).  The RX and TX
+ *   interrupts are not enabled until the txint() and rxint() methods are
+ *   called.
+ *
+ ****************************************************************************/
+
+static int up_attach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  int ret;
+
+  /* Attach and enable the IRQ */
+
+  ret = irq_attach(priv->irq, up_interrupt, dev);
+  if (ret == OK)
+    {
+      /* Set up to uart interrupts on the current CPU */
+
+       (void)s698pm_setup_irq(0, priv->irq, 0);
+
+      /* Enable the interrupt (RX and TX interrupts are still disabled
+       * in the USART
+       */
+
+       up_enable_irq(priv->irq);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_detach
+ *
+ * Description:
+ *   Detach UART interrupts.  This method is called when the serial port is
+ *   closed normally just before the shutdown method is called. The exception
+ *   is the serial console which is never shutdown.
+ *
+ ****************************************************************************/
+
+static void up_detach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Detach from the interrupt */
+
+  irq_detach(priv->irq);
+}
+
+/****************************************************************************
+ * Name: up_interrupt
+ *
+ * Description:
+ *   This is the UART interrupt handler.  It will be invoked when an
+ *   interrupt received on the 'irq'  It should call uart_transmitchars or
+ *   uart_receivechar to perform the appropriate data transfers.  The
+ *   interrupt handling logic must be able to map the 'irq' number into the
+ *   approprite uart_dev_s structure in order to call these functions.
+ *
+ ****************************************************************************/
+
+static int up_interrupt(int irq, void *context, void *arg)
+{
+  struct uart_dev_s *dev = (struct uart_dev_s *)arg;
+  struct up_dev_s   *priv;
+  uint32_t           mis;
+  int                passes;
+  bool               handled;
+
+  DEBUGASSERT(dev != NULL && dev->priv != NULL);
+  priv = (struct up_dev_s *)dev->priv;
+
+  /* Loop until there are no characters to be transferred or,
+   * until we have been looping for a long time.
+   */
+
+  handled = true;
+  for (passes = 0; passes < 256 && handled; passes++)
+    {
+      handled = false;
+
+      /* Get the masked UART status and clear the pending interrupts. */
+
+       mis = up_serialin(priv, S698PM_UART_STATREG_OFFSET);
+
+      /* Handle incoming, receive bytes */
+
+      if ((mis & UART_STA_DR) != 0)
+        {
+      /* Rx buffer not empty ... process incoming bytes */
+
+           uart_recvchars(dev);
+           handled = true;
+        }
+
+      /* Handle outgoing, transmit bytes */
+
+      if ((mis & UART_STA_TF) != UART_STA_TF)
+        {
+      /* Tx FIFO not full ... process outgoing bytes */

Review Comment:
   Please align!



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] masayuki2009 merged pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
masayuki2009 merged PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1006895682


##########
arch/sparc/src/sparc_v8/up_initialstate.c:
##########
@@ -71,7 +71,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == IDLE_PROCESS_ID)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
-                                      (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));
+                           (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));

Review Comment:
   it's simple, you may try this sequence:
   git rebase --interactive HEAD~2
   change pick to edit for the first patch
   make the change and git commit --amend
   git rebase --continue



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] xiaoxiang781216 commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1006804359


##########
arch/sparc/src/sparc_v8/up_initialstate.c:
##########
@@ -71,7 +71,7 @@ void up_initial_state(struct tcb_s *tcb)
   if (tcb->pid == IDLE_PROCESS_ID)
     {
       tcb->stack_alloc_ptr = (void *)(g_idle_topstack -
-                                      (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));
+                           (CONFIG_SMP_NCPUS * CONFIG_IDLETHREAD_STACKSIZE));

Review Comment:
   ok, should we move to the first patch?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] acassis commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
acassis commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1006889597


##########
arch/sparc/Kconfig:
##########
@@ -32,6 +32,19 @@ config ARCH_CHIP_BM3823
 	---help---
 		Microchip BM3823 (ARCH_SPARC_V8)
 
+config ARCH_CHIP_S698PM
+	bool "S698PM"
+	select ARCH_SPARC_V8
+	select ARCH_HAVE_MATH_H
+	select ARCH_HAVE_IRQPRIO
+	select ARCH_VECNOTIRQ
+	select ARCH_HAVE_RAMFUNCS
+	select ARCH_HAVE_MULTICPU
+	select ARCH_HAVE_TESTSET
+	select ARCH_HAVE_SERIAL_TERMIOS
+	---help---
+		Microchip S698PM (ARCH_SPARC_V8)

Review Comment:
   ```suggestion
   		ORBITA Sailing S698PM (ARCH_SPARC_V8)



##########
arch/sparc/Kconfig:
##########
@@ -32,6 +32,19 @@ config ARCH_CHIP_BM3823
 	---help---
 		Microchip BM3823 (ARCH_SPARC_V8)
 
+config ARCH_CHIP_S698PM
+	bool "S698PM"
+	select ARCH_SPARC_V8
+	select ARCH_HAVE_MATH_H
+	select ARCH_HAVE_IRQPRIO
+	select ARCH_VECNOTIRQ
+	select ARCH_HAVE_RAMFUNCS
+	select ARCH_HAVE_MULTICPU
+	select ARCH_HAVE_TESTSET
+	select ARCH_HAVE_SERIAL_TERMIOS
+	---help---
+		Microchip S698PM (ARCH_SPARC_V8)

Review Comment:
   Using Microchip (to indicate chip) could make people think that Microchip company created it.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] zouboan commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
zouboan commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1007600274


##########
arch/sparc/src/s698pm/s698pm-serial.c:
##########
@@ -0,0 +1,1037 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/s698pm-serial.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+#  include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <nuttx/spinlock.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "s698pm-config.h"
+#include "chip.h"
+#include "s698pm-uart.h"
+#include "s698pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If we are not using the serial driver for the console, then we still must
+ * provide some minimal implementation of up_putc.
+ */
+
+#ifdef USE_SERIALDRIVER
+
+/* Which UART with be tty0/console and which tty1?  The console will always
+ * be ttyS0.  If there is no console then will use the lowest numbered UART.
+ */
+
+/* First pick the console and ttys0.  This could be any of UART1-4 */
+
+#if defined(CONFIG_UART1_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart1port /* UART1 is console */
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart2port /* UART2 is console */
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart3port /* UART3 is console */
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#elif defined(CONFIG_UART4_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart4port /* UART4 is console */
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#else
+#  undef CONSOLE_DEV                        /* No console */
+#  if defined(CONFIG_S698PM_UART1)
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART2)
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART3)
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART4)
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#  endif
+#endif
+
+/* Pick ttys1.  This could be any of UART1-4 excluding the console UART. */
+
+#if defined(CONFIG_S698PM_UART1) && !defined(UART1_ASSIGNED)
+#  define TTYS1_DEV           g_uart1port /* UART1 is ttyS1 */
+#  define UART1_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS1_DEV           g_uart2port /* UART2 is ttyS1 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS1_DEV           g_uart3port /* UART3 is ttyS1 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS1_DEV           g_uart4port /* UART4 is ttyS1 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys2.  This could be one of UART2-4. It can't be UART1 because that
+ * was either assigned as ttyS0 or ttys1.  One of UART 1-4 could also be the
+ * console.
+ */
+
+#if defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS2_DEV           g_uart2port /* UART2 is ttyS2 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS2_DEV           g_uart3port /* UART3 is ttyS2 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS2_DEV           g_uart4port /* UART4 is ttyS2 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys3. This could be one of UART3-4. It can't be UART1-2 because
+ * those have already been assigned to ttsyS0, 1, or 2.  One of
+ * UART 2-4 could also be the console.
+ */
+
+#if defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS3_DEV           g_uart3port /* UART3 is ttyS3 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS3_DEV           g_uart4port /* UART4 is ttyS3 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Common initialization logic will not not know that the all of the UARTs
+ * have been disabled.  So, as a result, we may still have to provide
+ * stub implementations of up_earlyserialinit(), up_serialinit(), and
+ * up_putc().
+ */
+
+#ifdef HAVE_UART_DEVICE
+
+/* These values describe the set of enabled interrupts */
+
+#define RX_ENABLED(im)    (((im) & MSK_UART_ENABLE_RX) != 0)
+#define TX_ENABLED(im)    (((im) & MSK_UART_ENABLE_TX) != 0)
+
+#define ENABLE_RX(im)     do { (im) |= MSK_UART_ENABLE_RX; } while (0)
+#define ENABLE_TX(im)     do { (im) |= MSK_UART_ENABLE_TX; } while (0)
+
+#define DISABLE_RX(im)    do { (im) &= ~MSK_UART_ENABLE_RX; } while (0)
+#define DISABLE_TX(im)    do { (im) &= ~MSK_UART_ENABLE_TX; } while (0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct up_dev_s
+{
+  uintptr_t uartbase;  /* Base address of UART registers */
+  uint32_t  baud;      /* Configured baud */
+  uint8_t   irq;       /* IRQ associated with this UART (for attachment) */
+  uint8_t   im;        /* Interrupt mask state */
+  uint8_t   parity;    /* 0=none, 1=odd, 2=even */
+  uint8_t   bits;      /* Number of bits (5, 6, 7 or 8) */
+  bool      stopbits2; /* true: Configure with 2 stop bits instead of 1 */
+  spinlock_t lock;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers */
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset);
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value);
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im);
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im);
+
+/* Serial driver methods */
+
+static int  up_setup(struct uart_dev_s *dev);
+static void up_shutdown(struct uart_dev_s *dev);
+static int  up_attach(struct uart_dev_s *dev);
+static void up_detach(struct uart_dev_s *dev);
+static int  up_interrupt(int irq, void *context, void *arg);
+static int  up_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int  up_receive(struct uart_dev_s *dev, uint32_t *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+static void up_send(struct uart_dev_s *dev, int ch);
+static void up_txint(struct uart_dev_s *dev, bool enable);
+static bool up_txready(struct uart_dev_s *dev);
+static bool up_txempty(struct uart_dev_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct uart_ops_s g_uart_ops =
+{
+  .setup          = up_setup,
+  .shutdown       = up_shutdown,
+  .attach         = up_attach,
+  .detach         = up_detach,
+  .ioctl          = up_ioctl,
+  .receive        = up_receive,
+  .rxint          = up_rxint,
+  .rxavailable    = up_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = up_send,
+  .txint          = up_txint,
+  .txready        = up_txready,
+  .txempty        = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_S698PM_UART1
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART2
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART3
+static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART4
+static char g_uart3rxbuffer[CONFIG_UART4_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART4_TXBUFSIZE];
+#endif
+
+/* This describes the state of the S698PM UART1 port. */
+
+#ifdef CONFIG_S698PM_UART1
+static struct up_dev_s g_uart1priv =
+{
+  .uartbase  = S698PM_UART1_BASE,
+  .baud      = CONFIG_UART1_BAUD,
+  .irq       = S698PM_IRQ_UART_1_RX_TX,
+  .parity    = CONFIG_UART1_PARITY,
+  .bits      = CONFIG_UART1_BITS,
+  .stopbits2 = CONFIG_UART1_2STOP,
+};
+
+static uart_dev_t g_uart1port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART1_RXBUFSIZE,
+    .buffer  = g_uart1rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART1_TXBUFSIZE,
+    .buffer  = g_uart1txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart1priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART2 port. */
+
+#ifdef CONFIG_S698PM_UART2
+static struct up_dev_s g_uart2priv =
+{
+  .uartbase  = S698PM_UART2_BASE,
+  .baud      = CONFIG_UART2_BAUD,
+  .irq       = S698PM_IRQ_UART_2_RX_TX,
+  .parity    = CONFIG_UART2_PARITY,
+  .bits      = CONFIG_UART2_BITS,
+  .stopbits2 = CONFIG_UART2_2STOP,
+};
+
+static uart_dev_t g_uart2port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART2_RXBUFSIZE,
+    .buffer  = g_uart2rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART2_TXBUFSIZE,
+    .buffer  = g_uart2txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart2priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART3 port. */
+
+#ifdef CONFIG_S698PM_UART3
+static struct up_dev_s g_uart3priv =
+{
+  .uartbase  = S698PM_UART3_BASE,
+  .baud      = CONFIG_UART3_BAUD,
+  .irq       = S698PM_IRQ_UART_3_RX_TX,
+  .parity    = CONFIG_UART3_PARITY,
+  .bits      = CONFIG_UART3_BITS,
+  .stopbits2 = CONFIG_UART3_2STOP,
+};
+
+static uart_dev_t g_uart3port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART3_RXBUFSIZE,
+    .buffer  = g_uart3rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART3_TXBUFSIZE,
+    .buffer  = g_uart3txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart3priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART4 port. */
+
+#ifdef CONFIG_S698PM_UART4
+static struct up_dev_s g_uart4priv =
+{
+  .uartbase  = S698PM_UART4_BASE,
+  .baud      = CONFIG_UART4_BAUD,
+  .irq       = S698PM_IRQ_UART_4_RX_TX,
+  .parity    = CONFIG_UART4_PARITY,
+  .bits      = CONFIG_UART4_BITS,
+  .stopbits2 = CONFIG_UART4_2STOP,
+};
+
+static uart_dev_t g_uart4port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART4_RXBUFSIZE,
+    .buffer  = g_uart4rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART4_TXBUFSIZE,
+    .buffer  = g_uart4txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart4priv,
+};
+#endif
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_serialin
+ ****************************************************************************/
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset)
+{
+  return getreg32(priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_serialout
+ ****************************************************************************/
+
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value)
+{
+  putreg32(value, priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_setuartint
+ ****************************************************************************/
+
+static inline void up_setuartint(struct up_dev_s *priv)
+{
+  uint8_t regval;
+
+  regval   = up_serialin(priv, S698PM_UART_CTRLREG_OFFSET);
+  regval  &= ~MSK_UART_ALLINTS;
+  regval  |= priv->im;
+  up_serialout(priv, S698PM_UART_CTRLREG_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: up_restoreuartint
+ ****************************************************************************/
+
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  /* Re-enable/re-disable interrupts corresponding to the state of bits
+   * in im
+   */
+
+  flags = spin_lock_irqsave(&priv->lock);
+  priv->im  &= ~MSK_UART_ALLINTS;
+  priv->im  |= im;
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&priv->lock);
+  if (im)
+    {
+      *im = priv->im;
+    }
+
+  /* Disable all interrupts */
+
+  DISABLE_RX(priv->im);
+  DISABLE_TX(priv->im);
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_setup
+ *
+ * Description:
+ *   Configure the UART baud, bits, parity, etc. This method is called the
+ *   first time that the serial port is opened.
+ *
+ ****************************************************************************/
+
+static int up_setup(struct uart_dev_s *dev)
+{
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Configure the UART as an RS-232 UART */
+
+  s698pm_uartconfigure(priv->uartbase, priv->baud, priv->parity,
+                        priv->bits, priv->stopbits2);
+#endif
+
+#ifdef CONFIG_ARCH_IRQPRIO
+  /* Set up the interrupt priority */
+
+  up_prioritize_irq(priv->irq, priv->irqprio);
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_shutdown
+ *
+ * Description:
+ *   Disable the UART.  This method is called when the serial
+ *   port is closed
+ *
+ ****************************************************************************/
+
+static void up_shutdown(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Reset hardware and disable Rx and Tx */
+
+  s698pm_uartreset(priv->uartbase);
+}
+
+/****************************************************************************
+ * Name: up_attach
+ *
+ * Description:
+ *   Configure the UART to operation in interrupt driven mode. This method is
+ *   called when the serial port is opened.  Normally, this is just after the
+ *   the setup() method is called, however, the serial console may operate in
+ *   a non-interrupt driven mode during the boot phase.
+ *
+ *   RX and TX interrupts are not enabled by the attach method (unless the
+ *   hardware supports multiple levels of interrupt enabling).  The RX and TX
+ *   interrupts are not enabled until the txint() and rxint() methods are
+ *   called.
+ *
+ ****************************************************************************/
+
+static int up_attach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  int ret;
+
+  /* Attach and enable the IRQ */
+
+  ret = irq_attach(priv->irq, up_interrupt, dev);
+  if (ret == OK)
+    {
+      /* Set up to uart interrupts on the current CPU */
+
+       (void)s698pm_setup_irq(0, priv->irq, 0);
+
+      /* Enable the interrupt (RX and TX interrupts are still disabled
+       * in the USART
+       */
+
+       up_enable_irq(priv->irq);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_detach
+ *
+ * Description:
+ *   Detach UART interrupts.  This method is called when the serial port is
+ *   closed normally just before the shutdown method is called. The exception
+ *   is the serial console which is never shutdown.
+ *
+ ****************************************************************************/
+
+static void up_detach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Detach from the interrupt */
+
+  irq_detach(priv->irq);
+}
+
+/****************************************************************************
+ * Name: up_interrupt
+ *
+ * Description:
+ *   This is the UART interrupt handler.  It will be invoked when an
+ *   interrupt received on the 'irq'  It should call uart_transmitchars or
+ *   uart_receivechar to perform the appropriate data transfers.  The
+ *   interrupt handling logic must be able to map the 'irq' number into the
+ *   approprite uart_dev_s structure in order to call these functions.
+ *
+ ****************************************************************************/
+
+static int up_interrupt(int irq, void *context, void *arg)
+{
+  struct uart_dev_s *dev = (struct uart_dev_s *)arg;
+  struct up_dev_s   *priv;
+  uint32_t           mis;
+  int                passes;
+  bool               handled;
+
+  DEBUGASSERT(dev != NULL && dev->priv != NULL);
+  priv = (struct up_dev_s *)dev->priv;
+
+  /* Loop until there are no characters to be transferred or,
+   * until we have been looping for a long time.
+   */
+
+  handled = true;
+  for (passes = 0; passes < 256 && handled; passes++)
+    {
+      handled = false;
+
+      /* Get the masked UART status and clear the pending interrupts. */
+
+       mis = up_serialin(priv, S698PM_UART_STATREG_OFFSET);
+
+      /* Handle incoming, receive bytes */
+
+      if ((mis & UART_STA_DR) != 0)
+        {
+      /* Rx buffer not empty ... process incoming bytes */
+
+           uart_recvchars(dev);
+           handled = true;
+        }
+
+      /* Handle outgoing, transmit bytes */
+
+      if ((mis & UART_STA_TF) != UART_STA_TF)
+        {
+      /* Tx FIFO not full ... process outgoing bytes */

Review Comment:
   done



##########
arch/sparc/src/sparc_v8/up_schedulesigaction.c:
##########
@@ -175,3 +175,184 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
 
   leave_critical_section(flags);
 }
+#endif /* !CONFIG_SMP */
+
+#ifdef CONFIG_SMP
+void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
+{
+  irqstate_t flags;
+  int cpu;
+  int me;
+
+  sinfo("tcb=0x%p sigdeliver=0x%p\n", tcb, sigdeliver);
+
+  /* Make sure that interrupts are disabled */
+
+  flags = enter_critical_section();
+
+  /* Refuse to handle nested signal actions */
+
+  if (!tcb->xcp.sigdeliver)
+    {
+      /* First, handle some special cases when the signal is being delivered
+       * to task that is currently executing on any CPU.
+       */
+
+      sinfo("rtcb=0x%p CURRENT_REGS=0x%p\n", this_task(), CURRENT_REGS);
+
+      if (tcb->task_state == TSTATE_TASK_RUNNING)
+        {
+          me  = this_cpu();
+          cpu = tcb->cpu;
+
+          /* CASE 1:  We are not in an interrupt handler and a task is
+           * signaling itself for some reason.
+           */
+
+          if (cpu == me && !CURRENT_REGS)
+            {
+              /* In this case just deliver the signal now.
+               * REVISIT:  Signal handler will run in a critical section!
+               */
+
+              sigdeliver(tcb);
+            }
+
+          /* CASE 2:  The task that needs to receive the signal is running.
+           * This could happen if the task is running on another CPU OR if
+           * we are in an interrupt handler and the task is running on this
+           * CPU.  In the former case, we will have to PAUSE the other CPU
+           * first.  But in either case, we will have to modify the return
+           * state as well as the state in the TCB.
+           */
+
+          else
+            {
+              /* If we signaling a task running on the other CPU, we have
+               * to PAUSE the other CPU.
+               */
+
+              if (cpu != me)
+                {
+                  /* Pause the CPU */
+
+                  up_cpu_pause(cpu);
+
+                  /* Wait while the pause request is pending */
+
+                  while (up_cpu_pausereq(cpu))
+                    {
+                    }
+
+                  /* Now tcb on the other CPU can be accessed safely */
+
+                  /* Copy tcb->xcp.regs to tcp.xcp.saved. These will be
+                   * restored by the signal trampoline after the signal has
+                   * been delivered.
+                   */
+
+                  tcb->xcp.sigdeliver       = (FAR void *)sigdeliver;
+                  tcb->xcp.saved_pc         = tcb->xcp.regs[REG_PC];
+                  tcb->xcp.saved_npc        = tcb->xcp.regs[REG_NPC];
+                  tcb->xcp.saved_status     = tcb->xcp.regs[REG_PSR];
+
+                  /* Then set up vector to the trampoline with interrupts
+                   * disabled.  We must already be in privileged thread mode
+                   * to be here.
+                   */
+
+                  tcb->xcp.regs[REG_PC]     = (uint32_t)up_sigdeliver;
+                  tcb->xcp.regs[REG_NPC]    = (uint32_t)up_sigdeliver + 4;
+                  tcb->xcp.regs[REG_PSR]    |= SPARC_PSR_ET_MASK;
+                }
+              else
+                {
+                  /* tcb is running on the same CPU */
+
+                  /* Save registers that must be protected while the signal
+                   * handler runs. These will be restored by the signal
+                   * trampoline after the signal(s) have been delivered.
+                   */
+
+                  tcb->xcp.sigdeliver   = (FAR void *)sigdeliver;

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [incubator-nuttx] zouboan commented on a diff in pull request #7443: arch/sparc: add initial support for S698PM chip and SMP

Posted by GitBox <gi...@apache.org>.
zouboan commented on code in PR #7443:
URL: https://github.com/apache/incubator-nuttx/pull/7443#discussion_r1007600194


##########
arch/sparc/src/s698pm/s698pm-serial.c:
##########
@@ -0,0 +1,1037 @@
+/****************************************************************************
+ * arch/sparc/src/s698pm/s698pm-serial.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#ifdef CONFIG_SERIAL_TERMIOS
+#  include <termios.h>
+#endif
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/serial/serial.h>
+#include <nuttx/spinlock.h>
+#include <arch/board/board.h>
+
+#include "up_internal.h"
+#include "s698pm-config.h"
+#include "chip.h"
+#include "s698pm-uart.h"
+#include "s698pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If we are not using the serial driver for the console, then we still must
+ * provide some minimal implementation of up_putc.
+ */
+
+#ifdef USE_SERIALDRIVER
+
+/* Which UART with be tty0/console and which tty1?  The console will always
+ * be ttyS0.  If there is no console then will use the lowest numbered UART.
+ */
+
+/* First pick the console and ttys0.  This could be any of UART1-4 */
+
+#if defined(CONFIG_UART1_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart1port /* UART1 is console */
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart2port /* UART2 is console */
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#elif defined(CONFIG_UART3_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart3port /* UART3 is console */
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#elif defined(CONFIG_UART4_SERIAL_CONSOLE)
+#    define CONSOLE_DEV         g_uart4port /* UART4 is console */
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#else
+#  undef CONSOLE_DEV                        /* No console */
+#  if defined(CONFIG_S698PM_UART1)
+#    define TTYS0_DEV           g_uart1port /* UART1 is ttyS0 */
+#    define UART1_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART2)
+#    define TTYS0_DEV           g_uart2port /* UART2 is ttyS0 */
+#    define UART2_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART3)
+#    define TTYS0_DEV           g_uart3port /* UART3 is ttyS0 */
+#    define UART3_ASSIGNED      1
+#  elif defined(CONFIG_S698PM_UART4)
+#    define TTYS0_DEV           g_uart4port /* UART4 is ttyS0 */
+#    define UART4_ASSIGNED      1
+#  endif
+#endif
+
+/* Pick ttys1.  This could be any of UART1-4 excluding the console UART. */
+
+#if defined(CONFIG_S698PM_UART1) && !defined(UART1_ASSIGNED)
+#  define TTYS1_DEV           g_uart1port /* UART1 is ttyS1 */
+#  define UART1_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS1_DEV           g_uart2port /* UART2 is ttyS1 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS1_DEV           g_uart3port /* UART3 is ttyS1 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS1_DEV           g_uart4port /* UART4 is ttyS1 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys2.  This could be one of UART2-4. It can't be UART1 because that
+ * was either assigned as ttyS0 or ttys1.  One of UART 1-4 could also be the
+ * console.
+ */
+
+#if defined(CONFIG_S698PM_UART2) && !defined(UART2_ASSIGNED)
+#  define TTYS2_DEV           g_uart2port /* UART2 is ttyS2 */
+#  define UART2_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS2_DEV           g_uart3port /* UART3 is ttyS2 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS2_DEV           g_uart4port /* UART4 is ttyS2 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Pick ttys3. This could be one of UART3-4. It can't be UART1-2 because
+ * those have already been assigned to ttsyS0, 1, or 2.  One of
+ * UART 2-4 could also be the console.
+ */
+
+#if defined(CONFIG_S698PM_UART3) && !defined(UART3_ASSIGNED)
+#  define TTYS3_DEV           g_uart3port /* UART3 is ttyS3 */
+#  define UART3_ASSIGNED      1
+#elif defined(CONFIG_S698PM_UART4) && !defined(UART4_ASSIGNED)
+#  define TTYS3_DEV           g_uart4port /* UART4 is ttyS3 */
+#  define UART4_ASSIGNED      1
+#endif
+
+/* Common initialization logic will not not know that the all of the UARTs
+ * have been disabled.  So, as a result, we may still have to provide
+ * stub implementations of up_earlyserialinit(), up_serialinit(), and
+ * up_putc().
+ */
+
+#ifdef HAVE_UART_DEVICE
+
+/* These values describe the set of enabled interrupts */
+
+#define RX_ENABLED(im)    (((im) & MSK_UART_ENABLE_RX) != 0)
+#define TX_ENABLED(im)    (((im) & MSK_UART_ENABLE_TX) != 0)
+
+#define ENABLE_RX(im)     do { (im) |= MSK_UART_ENABLE_RX; } while (0)
+#define ENABLE_TX(im)     do { (im) |= MSK_UART_ENABLE_TX; } while (0)
+
+#define DISABLE_RX(im)    do { (im) &= ~MSK_UART_ENABLE_RX; } while (0)
+#define DISABLE_TX(im)    do { (im) &= ~MSK_UART_ENABLE_TX; } while (0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct up_dev_s
+{
+  uintptr_t uartbase;  /* Base address of UART registers */
+  uint32_t  baud;      /* Configured baud */
+  uint8_t   irq;       /* IRQ associated with this UART (for attachment) */
+  uint8_t   im;        /* Interrupt mask state */
+  uint8_t   parity;    /* 0=none, 1=odd, 2=even */
+  uint8_t   bits;      /* Number of bits (5, 6, 7 or 8) */
+  bool      stopbits2; /* true: Configure with 2 stop bits instead of 1 */
+  spinlock_t lock;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers */
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset);
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value);
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im);
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im);
+
+/* Serial driver methods */
+
+static int  up_setup(struct uart_dev_s *dev);
+static void up_shutdown(struct uart_dev_s *dev);
+static int  up_attach(struct uart_dev_s *dev);
+static void up_detach(struct uart_dev_s *dev);
+static int  up_interrupt(int irq, void *context, void *arg);
+static int  up_ioctl(struct file *filep, int cmd, unsigned long arg);
+static int  up_receive(struct uart_dev_s *dev, uint32_t *status);
+static void up_rxint(struct uart_dev_s *dev, bool enable);
+static bool up_rxavailable(struct uart_dev_s *dev);
+static void up_send(struct uart_dev_s *dev, int ch);
+static void up_txint(struct uart_dev_s *dev, bool enable);
+static bool up_txready(struct uart_dev_s *dev);
+static bool up_txempty(struct uart_dev_s *dev);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const struct uart_ops_s g_uart_ops =
+{
+  .setup          = up_setup,
+  .shutdown       = up_shutdown,
+  .attach         = up_attach,
+  .detach         = up_detach,
+  .ioctl          = up_ioctl,
+  .receive        = up_receive,
+  .rxint          = up_rxint,
+  .rxavailable    = up_rxavailable,
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+  .rxflowcontrol  = NULL,
+#endif
+  .send           = up_send,
+  .txint          = up_txint,
+  .txready        = up_txready,
+  .txempty        = up_txempty,
+};
+
+/* I/O buffers */
+
+#ifdef CONFIG_S698PM_UART1
+static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];
+static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART2
+static char g_uart2rxbuffer[CONFIG_UART2_RXBUFSIZE];
+static char g_uart2txbuffer[CONFIG_UART2_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART3
+static char g_uart3rxbuffer[CONFIG_UART3_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART3_TXBUFSIZE];
+#endif
+#ifdef CONFIG_S698PM_UART4
+static char g_uart3rxbuffer[CONFIG_UART4_RXBUFSIZE];
+static char g_uart3txbuffer[CONFIG_UART4_TXBUFSIZE];
+#endif
+
+/* This describes the state of the S698PM UART1 port. */
+
+#ifdef CONFIG_S698PM_UART1
+static struct up_dev_s g_uart1priv =
+{
+  .uartbase  = S698PM_UART1_BASE,
+  .baud      = CONFIG_UART1_BAUD,
+  .irq       = S698PM_IRQ_UART_1_RX_TX,
+  .parity    = CONFIG_UART1_PARITY,
+  .bits      = CONFIG_UART1_BITS,
+  .stopbits2 = CONFIG_UART1_2STOP,
+};
+
+static uart_dev_t g_uart1port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART1_RXBUFSIZE,
+    .buffer  = g_uart1rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART1_TXBUFSIZE,
+    .buffer  = g_uart1txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart1priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART2 port. */
+
+#ifdef CONFIG_S698PM_UART2
+static struct up_dev_s g_uart2priv =
+{
+  .uartbase  = S698PM_UART2_BASE,
+  .baud      = CONFIG_UART2_BAUD,
+  .irq       = S698PM_IRQ_UART_2_RX_TX,
+  .parity    = CONFIG_UART2_PARITY,
+  .bits      = CONFIG_UART2_BITS,
+  .stopbits2 = CONFIG_UART2_2STOP,
+};
+
+static uart_dev_t g_uart2port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART2_RXBUFSIZE,
+    .buffer  = g_uart2rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART2_TXBUFSIZE,
+    .buffer  = g_uart2txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart2priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART3 port. */
+
+#ifdef CONFIG_S698PM_UART3
+static struct up_dev_s g_uart3priv =
+{
+  .uartbase  = S698PM_UART3_BASE,
+  .baud      = CONFIG_UART3_BAUD,
+  .irq       = S698PM_IRQ_UART_3_RX_TX,
+  .parity    = CONFIG_UART3_PARITY,
+  .bits      = CONFIG_UART3_BITS,
+  .stopbits2 = CONFIG_UART3_2STOP,
+};
+
+static uart_dev_t g_uart3port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART3_RXBUFSIZE,
+    .buffer  = g_uart3rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART3_TXBUFSIZE,
+    .buffer  = g_uart3txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart3priv,
+};
+#endif
+
+/* This describes the state of the S698PM UART4 port. */
+
+#ifdef CONFIG_S698PM_UART4
+static struct up_dev_s g_uart4priv =
+{
+  .uartbase  = S698PM_UART4_BASE,
+  .baud      = CONFIG_UART4_BAUD,
+  .irq       = S698PM_IRQ_UART_4_RX_TX,
+  .parity    = CONFIG_UART4_PARITY,
+  .bits      = CONFIG_UART4_BITS,
+  .stopbits2 = CONFIG_UART4_2STOP,
+};
+
+static uart_dev_t g_uart4port =
+{
+  .recv      =
+  {
+    .size    = CONFIG_UART4_RXBUFSIZE,
+    .buffer  = g_uart4rxbuffer,
+  },
+  .xmit      =
+  {
+    .size    = CONFIG_UART4_TXBUFSIZE,
+    .buffer  = g_uart4txbuffer,
+  },
+  .ops       = &g_uart_ops,
+  .priv      = &g_uart4priv,
+};
+#endif
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_serialin
+ ****************************************************************************/
+
+static inline uint32_t up_serialin(struct up_dev_s *priv, int offset)
+{
+  return getreg32(priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_serialout
+ ****************************************************************************/
+
+static inline void up_serialout(struct up_dev_s *priv, int offset,
+                                uint32_t value)
+{
+  putreg32(value, priv->uartbase + offset);
+}
+
+/****************************************************************************
+ * Name: up_setuartint
+ ****************************************************************************/
+
+static inline void up_setuartint(struct up_dev_s *priv)
+{
+  uint8_t regval;
+
+  regval   = up_serialin(priv, S698PM_UART_CTRLREG_OFFSET);
+  regval  &= ~MSK_UART_ALLINTS;
+  regval  |= priv->im;
+  up_serialout(priv, S698PM_UART_CTRLREG_OFFSET, regval);
+}
+
+/****************************************************************************
+ * Name: up_restoreuartint
+ ****************************************************************************/
+
+static void up_restoreuartint(struct uart_dev_s *dev, uint8_t im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  /* Re-enable/re-disable interrupts corresponding to the state of bits
+   * in im
+   */
+
+  flags = spin_lock_irqsave(&priv->lock);
+  priv->im  &= ~MSK_UART_ALLINTS;
+  priv->im  |= im;
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_disableuartint
+ ****************************************************************************/
+
+static void up_disableuartint(struct uart_dev_s *dev, uint8_t *im)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&priv->lock);
+  if (im)
+    {
+      *im = priv->im;
+    }
+
+  /* Disable all interrupts */
+
+  DISABLE_RX(priv->im);
+  DISABLE_TX(priv->im);
+  up_setuartint(priv);
+  spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/****************************************************************************
+ * Name: up_setup
+ *
+ * Description:
+ *   Configure the UART baud, bits, parity, etc. This method is called the
+ *   first time that the serial port is opened.
+ *
+ ****************************************************************************/
+
+static int up_setup(struct uart_dev_s *dev)
+{
+#ifndef CONFIG_SUPPRESS_UART_CONFIG
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Configure the UART as an RS-232 UART */
+
+  s698pm_uartconfigure(priv->uartbase, priv->baud, priv->parity,
+                        priv->bits, priv->stopbits2);
+#endif
+
+#ifdef CONFIG_ARCH_IRQPRIO
+  /* Set up the interrupt priority */
+
+  up_prioritize_irq(priv->irq, priv->irqprio);
+#endif
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_shutdown
+ *
+ * Description:
+ *   Disable the UART.  This method is called when the serial
+ *   port is closed
+ *
+ ****************************************************************************/
+
+static void up_shutdown(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Reset hardware and disable Rx and Tx */
+
+  s698pm_uartreset(priv->uartbase);
+}
+
+/****************************************************************************
+ * Name: up_attach
+ *
+ * Description:
+ *   Configure the UART to operation in interrupt driven mode. This method is
+ *   called when the serial port is opened.  Normally, this is just after the
+ *   the setup() method is called, however, the serial console may operate in
+ *   a non-interrupt driven mode during the boot phase.
+ *
+ *   RX and TX interrupts are not enabled by the attach method (unless the
+ *   hardware supports multiple levels of interrupt enabling).  The RX and TX
+ *   interrupts are not enabled until the txint() and rxint() methods are
+ *   called.
+ *
+ ****************************************************************************/
+
+static int up_attach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+  int ret;
+
+  /* Attach and enable the IRQ */
+
+  ret = irq_attach(priv->irq, up_interrupt, dev);
+  if (ret == OK)
+    {
+      /* Set up to uart interrupts on the current CPU */
+
+       (void)s698pm_setup_irq(0, priv->irq, 0);
+
+      /* Enable the interrupt (RX and TX interrupts are still disabled
+       * in the USART
+       */
+
+       up_enable_irq(priv->irq);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: up_detach
+ *
+ * Description:
+ *   Detach UART interrupts.  This method is called when the serial port is
+ *   closed normally just before the shutdown method is called. The exception
+ *   is the serial console which is never shutdown.
+ *
+ ****************************************************************************/
+
+static void up_detach(struct uart_dev_s *dev)
+{
+  struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+
+  /* Disable interrupts */
+
+  up_disableuartint(dev, NULL);
+
+  /* Detach from the interrupt */
+
+  irq_detach(priv->irq);
+}
+
+/****************************************************************************
+ * Name: up_interrupt
+ *
+ * Description:
+ *   This is the UART interrupt handler.  It will be invoked when an
+ *   interrupt received on the 'irq'  It should call uart_transmitchars or
+ *   uart_receivechar to perform the appropriate data transfers.  The
+ *   interrupt handling logic must be able to map the 'irq' number into the
+ *   approprite uart_dev_s structure in order to call these functions.
+ *
+ ****************************************************************************/
+
+static int up_interrupt(int irq, void *context, void *arg)
+{
+  struct uart_dev_s *dev = (struct uart_dev_s *)arg;
+  struct up_dev_s   *priv;
+  uint32_t           mis;
+  int                passes;
+  bool               handled;
+
+  DEBUGASSERT(dev != NULL && dev->priv != NULL);
+  priv = (struct up_dev_s *)dev->priv;
+
+  /* Loop until there are no characters to be transferred or,
+   * until we have been looping for a long time.
+   */
+
+  handled = true;
+  for (passes = 0; passes < 256 && handled; passes++)
+    {
+      handled = false;
+
+      /* Get the masked UART status and clear the pending interrupts. */
+
+       mis = up_serialin(priv, S698PM_UART_STATREG_OFFSET);
+
+      /* Handle incoming, receive bytes */
+
+      if ((mis & UART_STA_DR) != 0)
+        {
+      /* Rx buffer not empty ... process incoming bytes */
+
+           uart_recvchars(dev);
+           handled = true;
+        }
+
+      /* Handle outgoing, transmit bytes */
+
+      if ((mis & UART_STA_TF) != UART_STA_TF)
+        {
+      /* Tx FIFO not full ... process outgoing bytes */
+
+      /* if (dev->xmit.head != dev->xmit.tail)
+       * {
+       */
+
+           uart_xmitchars(dev);
+           handled = true;
+
+      /* } */

Review Comment:
   done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org