Fixed C6670 SRIO boot issue
[keystone-rtos/mcsdk-tools.git] / boot_loader / examples / srio / srioboot_example / src / srioBootExample.c
index a74cd8a31636e93ac52a82e5cfc4a24f5c81fa5d..e2dcdc3b13557d448228080f4fe7090fbf62b2d7 100644 (file)
 #include <stdio.h>
 #include <string.h>
 #include "platform.h"
+#include "srioDdrInit.h"
 #include "srioBootCode.h"
+#include "ti/csl/csl_semAux.h"
 
-/* Magic address RBL is polling */
-#define BOOT_MAGIC_ADDR     0x1087fffc
+#define DEVICE_REG32_W(x,y)   *(volatile uint32_t *)(x)=(y)
+#define DEVICE_REG32_R(x)    (*(volatile uint32_t *)(x))
+
+#ifdef _EVMC6678L_
+#define MAGIC_ADDR     0x87fffc
+#endif
+
+#ifdef _EVMC6670L_
+#define MAGIC_ADDR     0x8ffffc
+#endif
+
+#define BOOT_MAGIC_ADDR(x)  (MAGIC_ADDR + (1<<28) + (x<<24))
 
 /* Entry address of the boot image */
 #define BOOT_ENTRY_ADDR     0xc000000
@@ -49,7 +61,7 @@
 #define WAIT_TIMEOUT        500000
 
 /* SRIO Boot Example Version */
-char version[] = "01.00.00.00";
+char version[] = "01.00.00.01";
 
 uint32_t coreNum;
 
@@ -63,21 +75,29 @@ volatile uint32_t bootEntryAddr = BOOT_ENTRY_ADDR;  /* Base address of MSMC */
 
 
 /* Port error status registers */
-uint32_t volatile *port_err_status_reg[] =  {
+#define SRIO_PORT_ERR_STATUS_REG(x)    (0x290b158 + x*0x20)
 
-    (uint32_t volatile *)0x290b158,
-    (uint32_t volatile *)0x290b178,
-    (uint32_t volatile *)0x290b198,
-    (uint32_t volatile *)0x290b1b8
-};
+/* OSAL functions for Platform Library */
+uint8_t *Osal_platformMalloc (uint32_t num_bytes, uint32_t alignment)
+{
+       return malloc(num_bytes);
+}
 
+void Osal_platformFree (uint8_t *dataPtr, uint32_t num_bytes)
+{
+    /* Free up the memory */
+    if (dataPtr)
+    {
+        free(dataPtr);
+    }
+}
 
 /* Convert bytes to 32 bits */
 uint32_t byteto32bits(uint8_t *pDspCode)
 {
     int32_t i;
     uint32_t temp;
-    
+
     temp = *pDspCode++;
     for(i=0; i<3;i++) {
         temp <<= 8;
@@ -86,26 +106,48 @@ uint32_t byteto32bits(uint8_t *pDspCode)
     return(temp);
 }
 
+void Osal_platformSpiCsEnter(void)
+{
+    /* Get the hardware semaphore.
+     *
+     * Acquire Multi core CPPI synchronization lock
+     */
+    while ((CSL_semAcquireDirect (3)) == 0);
+
+    return;
+}
+
+void Osal_platformSpiCsExit (void)
+{
+    /* Release the hardware semaphore
+     *
+     * Release multi-core lock.
+     */
+    CSL_semReleaseSemaphore (3);
+
+    return;
+}
+
 
 /* Convert to big endian, if the .out to be booted is big endian, this is not required */
-void 
+void
 Convert2BigEndian
 (
-    uint32_t    *pDspCode, 
+    uint32_t    *pDspCode,
     int32_t     size
 )
 {
     uint32_t i;
     uint32_t temp;
-    
+
     for(i=0; i<size; i+=4, pDspCode++) {
         temp = *pDspCode;
-        
-        temp = (temp>>24) | 
+
+        temp = (temp>>24) |
             ((temp<<8) & 0x00FF0000) |
             ((temp>>8) & 0x0000FF00) |
             (temp<<24);
-        
+
         *pDspCode= temp;
     }
 }
@@ -138,57 +180,56 @@ print_platform_errno
 
 
 /*
-Transfer (size_bytes) bytes data from host address (host_addr) to device ID's 
+Transfer (size_bytes) bytes data from host address (host_addr) to device ID's
 (rio_id) global address (dsp_addr). Lane 0 is used for booting.
 
-  rio_id:    destination device id 
+  rio_id:    destination device id
   host_addr:  host's address
   dsp_addr:   target dsp's global address
-  size_bytes: size in bytes 
+  size_bytes: size in bytes
 */
 int SRIOTransfer(int rio_num, int port_num, unsigned int host_addr, unsigned int dsp_addr, int size_bytes)
 {
     unsigned int count,busy;
-    
+
     /* Program a transfer on port 0 */
     /* LSU 1 Reg 0 - MSB of destination */
-    *((volatile uint32_t *)0x2900d00) = 0x00000000;
-    
-    
+    DEVICE_REG32_W(0x2900d00, 0x00000000);
+
+
     /* LSU 1 Reg 1 - LSB of destination */
-    *((volatile uint32_t *)0x2900d04) = dsp_addr;
-    
-    
+    DEVICE_REG32_W(0x2900d04, dsp_addr);
+
+
     /* LSU 1 Reg 2 - source address */
-    *((volatile uint32_t *)0x2900d08) = (1 << 28) | (coreNum << 24) | host_addr;
-    
-    
+    DEVICE_REG32_W(0x2900d08, (1 << 28) | (coreNum << 24) | host_addr);
+
+
     /* LSU 1 Reg 3 - Byte count */
-    *((volatile uint32_t *)0x2900d0c) = size_bytes;
-    
-    
-    /* LSU 1 Reg 4 - 
+    DEVICE_REG32_W(0x2900d0c, size_bytes);
+
+
+    /* LSU 1 Reg 4 -
     * out port ID = 0
     * Priority = 2
     * XAM = 0
     * ID size = 1 (16 bit)
     * Dest ID specified as arg
     * int32_terrupt request = 0 */
-    /* *((uint32_t *)0x2900d10) = 0x21000000 | (rio_id << 8)| (port << 30);  */
-    *((volatile uint32_t *)0x2900d10) = 0x00000000 | (rio_num << 8)| (port_num << 30);
-    
-    
+    DEVICE_REG32_W(0x2900d10, 0x00000000 | (rio_num << 8)| (port_num << 30));
+
+
     /* LSU 1 Reg 5 -
     * doorbell info = 0 for this packet type
     * hop count = 0 for this packet type
-    * Packet type = 0x54 - ftype = 5, ttype = 4 
+    * Packet type = 0x54 - ftype = 5, ttype = 4
     *                             nwrite packet type.
     * Writing this register should initiate the transfer */
-    *((volatile uint32_t *)0x2900d14) = 0x00000054;
-    
+    DEVICE_REG32_W(0x2900d14, 0x00000054);
+
     /* wait for it to complete */
     count = 0;
-    
+
     /* wait for it to complete */
     do{
         platform_delay(1);
@@ -196,70 +237,70 @@ int SRIOTransfer(int rio_num, int port_num, unsigned int host_addr, unsigned int
         if (count >= WAIT_TIMEOUT)
         {
             return (-1);
-        }        busy = *((volatile uint32_t *)0x2900d18);
-        
-    } while ((busy & 0x80000000) != 0x00000000); 
-    
+        }        busy = DEVICE_REG32_R(0x2900d18);
+
+    } while ((busy & 0x80000000) != 0x00000000);
+
     return(0);
 }
 
 
-/* Send boot tables to DSP and then door bell interrupt to boot the DSP
+/* Send boot tables to DSP and then write the magic address to boot the DSP
 
 pDspCode: points to DSP code;
 DeviceID: device ID.
 
 */
-int32_t bootDSP(uint8_t *pDspCode,int32_t DeviceID)
+int32_t pushData2Srio(uint8_t *pDspCode,int32_t DeviceID)
 {
     uint32_t i;
     uint32_t size;
     uint32_t count, remainder;
     uint32_t startaddr;
     volatile uint32_t vx;
-    
-    
+
+
     /* Claim the LSU */
-    vx = *((volatile uint32_t *)0x2900d18);
+    vx = DEVICE_REG32_R(0x2900d18);
 
     /* Get the boot entry address */
     bootEntryAddr = byteto32bits(pDspCode);
     pDspCode +=4;
-    
+
     while(1) {
-        
+
         /* Get the size */
         size =         byteto32bits(pDspCode);
         if(size == 0) break;
         pDspCode += 4;
-        
+
         startaddr = byteto32bits(pDspCode);
         pDspCode+= 4;
-        
+
         count = size/MAX_TX_SIZE;
         remainder = size - count * MAX_TX_SIZE;
-        
+
         for(i=0; i<count; i++) {
-            /* This is not needed if the .out to be booted is big endian already */                    
+            /* This is not needed if the .out to be booted is big endian already */
             Convert2BigEndian((uint32_t *)pDspCode,MAX_TX_SIZE);
-            
+
             /* Transfer boot tables to DSP */
             if(SRIOTransfer(rio_id, port, (uint32_t )pDspCode, (uint32_t )startaddr, MAX_TX_SIZE)!=0) return(-1);
             pDspCode += MAX_TX_SIZE;
             startaddr += MAX_TX_SIZE;
         }
-        
-        /* This is not needed if the .out to be booted is big endian already */                        
+
+        /* This is not needed if the .out to be booted is big endian already */
         Convert2BigEndian((uint32_t *)pDspCode,remainder);
-        
+
         if(SRIOTransfer(rio_id, port,(uint32_t )pDspCode, (uint32_t )startaddr, remainder)!=0) return(-1);
         pDspCode += remainder;
     }
-    
-    /* Write to magic address to start booting */
-    if (SRIOTransfer(rio_id, port,(uint32_t )&bootEntryAddr, BOOT_MAGIC_ADDR, 4)!=0)
+
+    /* Write to Core 0 boot magic address to boot Core 0 */
+    if (SRIOTransfer(rio_id, port,(uint32_t )&bootEntryAddr, BOOT_MAGIC_ADDR(0), 4)!=0)
         return(-1);
-    
+
     return(0);
 }
 
@@ -268,55 +309,55 @@ int32_t bootDSP(uint8_t *pDspCode,int32_t DeviceID)
 /******************************************************************************
  * Function:    Send a maintenance packet
  ******************************************************************************/
-void 
+void
 mainPacket
 (
-    uint32_t    addr, 
+    uint32_t    addr,
     uint32_t    value
 )
 {
     volatile uint32_t vx;
     uint32_t busy, count;
-    
+
     value = swap(value);
-    
+
     /* Claim the LSU */
-    vx = *((volatile uint32_t *)0x2900d18);
-    
+    vx = DEVICE_REG32_R(0x2900d18);
+
     /* Program a transfer on port 0 */
     /* LSU 1 Reg 0 - MSB of destination */
-    *((volatile uint32_t *)0x2900d00) = 0x00000000;
-    
-    
+    DEVICE_REG32_W(0x2900d00, 0x00000000);
+
+
     /* LSU 1 Reg 1 - LSB of destination */
-    *((volatile uint32_t *)0x2900d04) = addr - 0x290b000;
-    
+    DEVICE_REG32_W(0x2900d04, addr - 0x290b000);
+
     /* LSU 1 Reg 2 - source address */
-    *((volatile uint32_t *)0x2900d08) = (1 << 28) | (coreNum << 24) | (uint32_t)&value;
-    
-    
+    DEVICE_REG32_W(0x2900d08, (1 << 28) | (coreNum << 24) | (uint32_t)&value);
+
+
     /* LSU 1 Reg 3 - Byte count */
-    *((volatile uint32_t *)0x2900d0c) = 4;
-    
-    /* LSU 1 Reg 4 - 
+    DEVICE_REG32_W(0x2900d0c, 4);
+
+    /* LSU 1 Reg 4 -
     * out port ID = 0
     * Priority = 2
     * XAM = 0
     * ID size = 1 (16 bit)
     * Dest ID specified as arg
     * int32_terrupt request = 0 */
-    *((volatile uint32_t *)0x2900d10) = 0xffff0000 | (port << 8);
-    
-    
+    DEVICE_REG32_W(0x2900d10, 0xffff0000 | (port << 8));
+
+
     /* LSU 1 Reg 5 -
     * doorbell info = 0 for this packet type
     * hop count = 0 for this packet type
-    * Packet type = 0x54 - ftype = 5, ttype = 4 
+    * Packet type = 0x54 - ftype = 5, ttype = 4
     *                             nwrite packet type.
     * Writing this register should initiate the transfer */
     /*  *((uint32_t *)0x2900d14) = 0x00000054;  */
-    *((volatile uint32_t *)0x2900d14) = 0x00000081;  /* maint32_tenance write */
-    
+    DEVICE_REG32_W(0x2900d14, 0x00000081);  /* maint32_tenance write */
+
     /* wait for it to complete */
     count = 0;
     do{
@@ -326,10 +367,10 @@ mainPacket
         {
             printf("Send a maintenance packet failed\n");
             return;
-        }        
-        busy = *((volatile uint32_t *)0x2900d18);
-        
-    } while ((busy & 0x80000000) != 0x00000000);     
+        }
+        busy = DEVICE_REG32_R(0x2900d18);
+
+    } while ((busy & 0x80000000) != 0x00000000);
 
     return;
 }
@@ -338,34 +379,34 @@ mainPacket
 int32_t SRIOPortStatus(uint32_t port_num)
 {
     uint32_t count,value,portok;
-    
+
     count = 0;
     portok= 0;
 
     while(1)
-    {   
-        value = *port_err_status_reg[port_num];
-        
-        if((value & 0x02) !=0) 
+    {
+        value = DEVICE_REG32_R(SRIO_PORT_ERR_STATUS_REG(port_num));
+
+        if((value & 0x02) !=0)
         {
-            portok++; 
-            if(portok >= 50) 
+            portok++;
+            if(portok >= 50)
             {
                 break; /* port must be solid OK */
             }
-        } 
-        else 
+        }
+        else
         {
             portok = 0;
             count++;
-            if (count >= WAIT_TIMEOUT) 
+            if (count >= WAIT_TIMEOUT)
             {
                 return(-1);
             }
         }
         platform_delay(1);
     }
-    
+
     return(0);
 }
 
@@ -377,12 +418,12 @@ srio_init
 )
 {
     /* Enable the Transmit register */
-    *((volatile uint32_t *)0x290b13c) = 0x40000000;
+    DEVICE_REG32_W(0x290b13c, 0x40000000);
 
     if (loopback)
     {
         /* Enable Lane loop back for all the ports */
-        *((volatile uint32_t *)0x2900018) = 0x000000f0;
+        DEVICE_REG32_W(0x2900018, 0x000000f0);
     }
 
     /* check for the port status */
@@ -399,10 +440,9 @@ srio_init
 
 void main (void)
 {
-    volatile uint32_t       vx;
     platform_init_flags     init_flags;
     platform_init_config    init_config;
-    char                    version_msg[] = "\r\n\r\nSRIO Boot Example Version ";
+    char                    version_msg[] = "\r\n\r\nSRIO Boot Host Example Version ";
 
     printf("%s%s\n\n", version_msg, version);
 
@@ -419,18 +459,30 @@ void main (void)
     coreNum = platform_get_coreid();
 
     /* Init port 0, disable loopback */
-    srio_init(port, loopback);    
-    
-    /* Boot the DSP */
-    if(bootDSP(bootCode, rio_id)==0)
+    srio_init(port, loopback);
+
+    /* Push the DDR init code to remote DSP core 0 and boot core 0 to initialize the DDR */
+    if(pushData2Srio(ddrInitCode, rio_id)==0)
     {
-        printf("DSP boot successful\n");
-    } 
-    else 
+        printf("Transfer DDR init code via SRIO successfully\n");
+
+        platform_delay(100000);
+
+        /* Push the boot image code to remote DSP DDR and boot core 0 to run Hello World */
+        if(pushData2Srio(bootCode, rio_id)==0)
+        {
+            printf("Transfer boot code via SRIO successfully\n");
+        }
+        else
+        {
+            printf("DSP boot failed.\n");
+        }
+    }
+    else
     {
         printf("DSP boot failed.\n");
     }
-    
+
     for (;;);
 
 }