Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:52

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * RTEMS generic MPC5200 BSP
0005  *
0006  * This file contains glue functions to the Freescale BestComm API.
0007  */
0008 
0009 /*
0010  * Copyright (C) 2004, 2005 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 #include <assert.h>
0035 #include <rtems.h>
0036 #include <bsp.h>
0037 #include <bsp/irq.h>
0038 #include <bsp/mpc5200.h>
0039 #include <bsp/bestcomm/include/ppctypes.h> /* uint32, et. al.          */
0040 #include <bsp/bestcomm/dma_image.h>
0041 #include <bsp/bestcomm/task_api/bestcomm_cntrl.h>
0042 #include <bsp/bestcomm/bestcomm_api.h>
0043 #include <bsp/bestcomm/bestcomm_glue.h>
0044 #include <bsp/bestcomm/include/mgt5200/sdma.h>
0045 #include <rtems/score/heapimpl.h>
0046 
0047 extern const uint32 taskTableBytes;
0048 
0049 static Heap_Control bestcomm_heap;
0050 
0051 /*=========================================================================*\
0052 | Function:                                                                 |
0053 \*-------------------------------------------------------------------------*/
0054 void bestcomm_glue_irq_enable
0055 (
0056 /*-------------------------------------------------------------------------*\
0057 | Purpose:                                                                  |
0058 |   enable interrupt for given task number                                  |
0059 +---------------------------------------------------------------------------+
0060 | Input Parameters:                                                         |
0061 \*-------------------------------------------------------------------------*/
0062  int bestcomm_taskno                           /* task number to enable    */
0063 )
0064 /*-------------------------------------------------------------------------*\
0065 | Return Value:                                                             |
0066 |    none                                                                   |
0067 \*=========================================================================*/
0068 {
0069   if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) {
0070     /*
0071      * valid task number
0072      * enable interrupt in bestcomm mask
0073      */
0074     SDMA_INT_ENABLE(&mpc5200.sdma.IntMask,bestcomm_taskno);
0075   }
0076 }
0077 
0078 /*=========================================================================*\
0079 | Function:                                                                 |
0080 \*-------------------------------------------------------------------------*/
0081 void bestcomm_glue_irq_disable
0082 (
0083 /*-------------------------------------------------------------------------*\
0084 | Purpose:                                                                  |
0085 |   disable interrupt for given task number                                 |
0086 +---------------------------------------------------------------------------+
0087 | Input Parameters:                                                         |
0088 \*-------------------------------------------------------------------------*/
0089  int bestcomm_taskno                           /* task number to disable   */
0090 )
0091 /*-------------------------------------------------------------------------*\
0092 | Return Value:                                                             |
0093 |    none                                                                   |
0094 \*=========================================================================*/
0095 {
0096   if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) {
0097     /*
0098      * valid task number
0099      * disable interrupt in bestcomm mask
0100      */
0101     SDMA_INT_DISABLE(&mpc5200.sdma.IntMask,bestcomm_taskno);
0102   }
0103 }
0104 
0105 typedef struct {
0106   rtems_interrupt_handler handler;
0107   void *arg;
0108 } bestcomm_glue_irq_handlers_t;
0109 
0110 static bestcomm_glue_irq_handlers_t bestcomm_glue_irq_handlers[32];
0111 
0112 /*=========================================================================*\
0113 | Function:                                                                 |
0114 \*-------------------------------------------------------------------------*/
0115 void bestcomm_glue_irq_install
0116 (
0117 /*-------------------------------------------------------------------------*\
0118 | Purpose:                                                                  |
0119 |   install given function as bestcomm interrupt handler                    |
0120 +---------------------------------------------------------------------------+
0121 | Input Parameters:                                                         |
0122 \*-------------------------------------------------------------------------*/
0123  int bestcomm_taskno,                          /* task number for handler  */
0124  rtems_interrupt_handler handler,              /* function to call         */
0125  void *arg
0126 )
0127 /*-------------------------------------------------------------------------*\
0128 | Return Value:                                                             |
0129 |    none                                                                   |
0130 \*=========================================================================*/
0131 {
0132   if (0 != ((1UL<<bestcomm_taskno) & SDMA_INT_BIT_IMPL)) {
0133     /*
0134      * valid task number
0135      * install handler
0136      */
0137     bestcomm_glue_irq_handlers[bestcomm_taskno].handler = handler;
0138     bestcomm_glue_irq_handlers[bestcomm_taskno].arg = arg;
0139   }
0140 }
0141 
0142 /*=========================================================================*\
0143 | Function:                                                                 |
0144 \*-------------------------------------------------------------------------*/
0145 static void bestcomm_glue_irq_dispatcher
0146 (
0147 /*-------------------------------------------------------------------------*\
0148 | Purpose:                                                                  |
0149 |   general bestcomm interrupt handler/dispatcher                           |
0150 +---------------------------------------------------------------------------+
0151 | Input Parameters:                                                         |
0152 \*-------------------------------------------------------------------------*/
0153  void *arg                               /* irq specific handle (not used) */
0154 )
0155 /*-------------------------------------------------------------------------*\
0156 | Return Value:                                                             |
0157 |    none                                                                   |
0158 \*=========================================================================*/
0159 {
0160   uint32_t pending;
0161   int curr_taskno;
0162 
0163   pending = mpc5200.sdma.IntPend & ~mpc5200.sdma.IntMask;
0164   curr_taskno = 0;
0165   while (pending != 0) {
0166     if ((pending & (1UL<<curr_taskno)) != 0) {
0167       if (bestcomm_glue_irq_handlers[curr_taskno].handler != NULL) {
0168     /*
0169      * call proper handler
0170      */
0171     bestcomm_glue_irq_handlers[curr_taskno].handler
0172       (bestcomm_glue_irq_handlers[curr_taskno].arg);
0173       }
0174       else {
0175     /*
0176      * This should never happen. we have a pending IRQ but no handler
0177      * let's clear this pending bit
0178      */
0179     SDMA_CLEAR_IEVENT(&mpc5200.sdma.IntPend,curr_taskno);
0180       }
0181       /*
0182        * clear this bit in our pending copy
0183        * and go to next bit
0184        */
0185       pending &= ~(1<<curr_taskno);
0186     }
0187     curr_taskno++;
0188   }
0189 }
0190 
0191 static bool bestcomm_glue_is_initialized = false;
0192 /*=========================================================================*\
0193 | Function:                                                                 |
0194 \*-------------------------------------------------------------------------*/
0195 void bestcomm_glue_init
0196 (
0197 /*-------------------------------------------------------------------------*\
0198 | Purpose:                                                                  |
0199 |   initialize the bestcomm module (if not yet done):                       |
0200 |   - load code                                                             |
0201 |   - initialize registers                                                  |
0202 |   - initialize bus arbiter                                                |
0203 |   - initialize interrupt control                                          |
0204 +---------------------------------------------------------------------------+
0205 | Input Parameters:                                                         |
0206 \*-------------------------------------------------------------------------*/
0207  void /* none */
0208 )
0209 /*-------------------------------------------------------------------------*\
0210 | Return Value:                                                             |
0211 |    none                                                                   |
0212 \*=========================================================================*/
0213 {
0214   rtems_status_code sc = RTEMS_SUCCESSFUL;
0215   uintptr_t heap_status = 0;
0216 
0217   if (!bestcomm_glue_is_initialized) {
0218     bestcomm_glue_is_initialized = true;
0219 
0220     heap_status = _Heap_Initialize(
0221       &bestcomm_heap,
0222       (char *) &mpc5200.sram [0] + taskTableBytes,
0223       sizeof(mpc5200.sram) - taskTableBytes,
0224       4
0225     );
0226     assert(heap_status != 0);
0227 
0228     /*
0229      * Set task bar to begin of sram
0230      */
0231     mpc5200.sdma.taskBar = (uint32_t)(&(mpc5200.sram[0]));
0232 
0233 #if 0
0234     /*
0235      * Set core and BestComm XLB priority the same.
0236      */
0237     mpc5200.priority_enable |= 0x5;
0238     mpc5200.priority = 0x77777171;
0239 #endif
0240 
0241     /*
0242      * Turn off COMM bus prefetch. This affects all data movements on
0243      * the COMM bus. (Yes, _PE -- prefetch enable -- should probably be
0244      * named _PD.)
0245      */
0246     mpc5200.sdma.PtdCntrl |= SDMA_PTDCNTRL_PE;
0247 
0248     TasksInitAPI((uint8*)&mpc5200);
0249 
0250     TasksLoadImage( (void *)&(mpc5200.sdma.taskBar));
0251 
0252     /*
0253      * initialize interrupt dispatcher
0254      */
0255     sc = rtems_interrupt_handler_install(
0256       BSP_SIU_IRQ_SMARTCOMM,
0257       "BESTCOMM",
0258       RTEMS_INTERRUPT_UNIQUE,
0259       bestcomm_glue_irq_dispatcher,
0260       NULL
0261     );
0262     assert(sc == RTEMS_SUCCESSFUL);
0263   }
0264 }
0265 
0266 void *bestcomm_malloc(size_t size)
0267 {
0268   return _Heap_Allocate(&bestcomm_heap, size);
0269 }
0270 
0271 void bestcomm_free(void *ptr)
0272 {
0273   if (ptr != NULL) {
0274     bool ok = _Heap_Free(&bestcomm_heap, ptr);
0275     assert(ok);
0276   }
0277 }