Port makefiles to Linux (while still supporting Windows)
[keystone-rtos/ibl.git] / src / interp / btbl / gem.c
1 /**********************************************************************************************************
2  * FILE PURPOSE: Support functions specific to gem
3  **********************************************************************************************************
4  * FILE NAME: gem.c
5  *
6  * DESCRIPTION: Contains functions common to all gem devices.
7  *
8  **********************************************************************************************************/
9 #include "types.h"
10 #include "btblwrap.h"
12 extern volatile cregister unsigned int CSR;
13 #define C64X_REG_CSR_BIT_EN (1 << 8)
15 /************************************************************************************
16  * FUNCTION PURPOSE: Copy data from the boot table to the destination locations
17  ************************************************************************************
18  * DESCRIPTION: Copy data from the boot table to the destination. 
19  *
20  *              The input data is interpreted as 32 bit values, made up of two 16 
21  *              bit values in big endian format. This is done to acheive endian
22  *              independence on the c64x. 
23  *
24  *              If the size is not evenly divisible by 4 then the final write does a
25  *              read first, and writes the most significant bytes back. 
26  ************************************************************************************/
27 UINT16 coreCopyData (UINT32 dest_addr, UINT16 *p_data, UINT32 sizeBytes, UINT16 start_vector)
28 {
29   UINT32  value;
30   UINT32  insert;
31   UINT32  i;
32   UINT32  j;
33   UINT32  n32;
34   UINT32  rb;
36   UINT32  *restrict rdest;
37   UINT16  *restrict rsrc;
39   chipDummy ((void *)start_vector);
41   n32 = sizeBytes >> 2;
44   /* If the destination address is 32 bit aligned an unaligned copy is not requird */
45   if ((dest_addr & 0x3) == 0)  {
47     rdest = (UINT32 *)dest_addr;
48     rsrc  = p_data;
50     for (i = j = 0; i < n32; i++, j += 2)  {
52       value = (((UINT32)rsrc[j]) << 16) | (rsrc[j+1]);
53       rdest[i] = value;
55     }
57     dest_addr += (n32 << 2);
60   }  else  {
62     /* Do whole 32 bit writes first */
63     for (i = j = 0; i < n32; i++, j += 2)  {
65       value = (((UINT32)p_data[j]) << 16) | (p_data[j+1]);
66       chipStoreWord ((UINT32 *)dest_addr, value);
67       dest_addr += 4;
69     }
71   }
73   /* Handle any remaining values based on the endian of the device */
74   rb = sizeBytes - (n32 << 2);
76   if (rb != 0)  {
78     value = chipReadWord ((UINT32 *)dest_addr);
80     if ((CSR & C64X_REG_CSR_BIT_EN) != 0)  {
82       /* Little endian. Put remaining bytes in the least significant value */
83       if (rb >= 1)  {
84         insert = (p_data[j] >> 8) & 0x00ff;
85         value = (value & 0xffffff00) | insert;
87       } 
89       if (rb >= 2)  {
90         insert = p_data[j] & 0x00ff;
91         value = (value & 0xffff00ff) | (insert << 8);
93       } 
94       
95       if (rb >= 3)  {
96         insert = (p_data[j+1] >> 8) & 0x00ff;
97         value = (value & 0xff00ffff) | (insert << 16);
98       }
100     } else  {
102       /* Bit endian. Put remaining bytes in the most significant value */
103       if (rb == 1)  {
104         insert = (p_data[j] >> 8) & 0xff;
105         value = (value & 0x00ffffff) | (insert << 24);
106       
107       } else if (rb == 2)  {
108         insert = p_data[j] & 0xffff;
109         value = (value & 0x0000ffff) | (insert << 16);
111       } else if (rb == 3)  {
112         insert = ((p_data[j] << 8) | (p_data[j+1] >> 8)) & 0x00ffffff;
113         value = (value & 0x000000ff) | (insert << 8);
114       }
116     }
118    chipStoreWord ((UINT32 *)dest_addr, value);
120   }
123   return (CORE_NOERR);
125 } /* coreCopyData */