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 }
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);
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 */