1 | /************************************************************************** |
---|
2 | * |
---|
3 | * Copyright (c) 2013 Alcatel-Lucent |
---|
4 | * |
---|
5 | * Alcatel Lucent licenses this file to You under the Apache License, |
---|
6 | * Version 2.0 (the "License"); you may not use this file except in |
---|
7 | * compliance with the License. A copy of the License is contained the |
---|
8 | * file LICENSE at the top level of this repository. |
---|
9 | * You may also obtain a copy of the License at: |
---|
10 | * |
---|
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
---|
12 | * |
---|
13 | * Unless required by applicable law or agreed to in writing, software |
---|
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
---|
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
---|
16 | * See the License for the specific language governing permissions and |
---|
17 | * limitations under the License. |
---|
18 | * |
---|
19 | ************************************************************************** |
---|
20 | * |
---|
21 | * cstart.c: |
---|
22 | * This is the first 'C' code exececuted by the processor after a reset if |
---|
23 | * the monitor is built to boot and copy itself into RAM. |
---|
24 | * |
---|
25 | * This 2-stage monitor is done with two distinct images. |
---|
26 | * The first image (the real "boot" image) includes this cstart() code |
---|
27 | * in place of normal start(). The make process generates the umon.c file |
---|
28 | * included below. This file is essentially a C-array that consists of |
---|
29 | * the binary image (second image) of a version of the monitor that is |
---|
30 | * built to run out of RAM. The value of UMON_RAMBASE is the base address |
---|
31 | * of this image and the value of UMON_START is the entry point into this |
---|
32 | * image. |
---|
33 | * |
---|
34 | * Original author: Ed Sutter (ed.sutter@alcatel-lucent.com) |
---|
35 | * |
---|
36 | */ |
---|
37 | #include "config.h" |
---|
38 | #include "stddefs.h" |
---|
39 | #include "cpu.h" |
---|
40 | |
---|
41 | #ifdef ROM_MONSTACKSIZE |
---|
42 | ulong MonStack[ROM_MONSTACKSIZE/4]; |
---|
43 | #endif |
---|
44 | |
---|
45 | /* The umon.c file is simply an array that contains the monitor |
---|
46 | * image and the necessary information needed to do the copy. |
---|
47 | */ |
---|
48 | #include "umon.c" |
---|
49 | |
---|
50 | char * |
---|
51 | memcpy(char *to,char *from,int count) |
---|
52 | { |
---|
53 | char *to_copy, *end; |
---|
54 | |
---|
55 | to_copy = to; |
---|
56 | |
---|
57 | /* If count is greater than 8, get fancy, else just do byte-copy... */ |
---|
58 | if (count > 8) { |
---|
59 | /* Attempt to optimize the transfer here... */ |
---|
60 | if (((int)to & 3) && ((int)from & 3)) { |
---|
61 | /* If from and to pointers are both unaligned to the |
---|
62 | * same degree then we can do a few char copies to get them |
---|
63 | * 4-byte aligned and then do a lot of 4-byte aligned copies. |
---|
64 | */ |
---|
65 | if (((int)to & 3) == ((int)from & 3)) { |
---|
66 | while((int)to & 3) { |
---|
67 | *to++ = *from++; |
---|
68 | count--; |
---|
69 | } |
---|
70 | } |
---|
71 | /* If from and to pointers are both odd, but different, then |
---|
72 | * we can increment them both by 1 and do a bunch of 2-byte |
---|
73 | * aligned copies... |
---|
74 | */ |
---|
75 | else if (((int)to & 1) && ((int)from & 1)) { |
---|
76 | *to++ = *from++; |
---|
77 | count--; |
---|
78 | } |
---|
79 | } |
---|
80 | |
---|
81 | /* If both pointers are now 4-byte aligned or 2-byte aligned, |
---|
82 | * take advantage of that here... |
---|
83 | */ |
---|
84 | if (!((int)to & 3) && !((int)from & 3)) { |
---|
85 | end = to + (count & ~3); |
---|
86 | count = count & 3; |
---|
87 | while(to < end) { |
---|
88 | *(ulong *)to = *(ulong *)from; |
---|
89 | from += 4; |
---|
90 | to += 4; |
---|
91 | } |
---|
92 | } |
---|
93 | else if (!((int)to & 1) && !((int)from & 1)) { |
---|
94 | end = to + (count & ~1); |
---|
95 | count = count & 1; |
---|
96 | while(to < end) { |
---|
97 | *(ushort *)to = *(ushort *)from; |
---|
98 | from += 2; |
---|
99 | to += 2; |
---|
100 | } |
---|
101 | } |
---|
102 | } |
---|
103 | |
---|
104 | if (count) { |
---|
105 | end = to + count; |
---|
106 | while(to < end) |
---|
107 | *to++ = *from++; |
---|
108 | } |
---|
109 | return(to_copy); |
---|
110 | } |
---|
111 | |
---|
112 | void |
---|
113 | cstart(void) |
---|
114 | { |
---|
115 | register long *lp1, *lp2, *end2; |
---|
116 | void (*entry)(); |
---|
117 | |
---|
118 | entry = (void(*)())UMON_START; |
---|
119 | |
---|
120 | /* Copy image from boot flash to RAM, then verify the copy. |
---|
121 | * If it worked, then jump into that space; else reset and start |
---|
122 | * over (not much else can be done!). |
---|
123 | */ |
---|
124 | memcpy((char *)UMON_RAMBASE,(char *)umon,(int)sizeof(umon)); |
---|
125 | |
---|
126 | /* Verify the copy... |
---|
127 | */ |
---|
128 | lp1 = (long *)UMON_RAMBASE; |
---|
129 | lp2 = (long *)umon; |
---|
130 | end2 = lp2 + (int)sizeof(umon)/sizeof(long); |
---|
131 | while(lp2 < end2) { |
---|
132 | if (*lp1 != *lp2) { |
---|
133 | #ifdef CSTART_ERROR_FUNCTION |
---|
134 | extern void CSTART_ERROR_FUNCTION(); |
---|
135 | |
---|
136 | CSTART_ERROR_FUNCTION(lp1,*lp1,*lp2); |
---|
137 | #endif |
---|
138 | #ifdef INLINE_RESETFUNC |
---|
139 | INLINE_RESETFUNC(); |
---|
140 | #else |
---|
141 | entry = RESETFUNC(); |
---|
142 | #endif |
---|
143 | break; |
---|
144 | } |
---|
145 | lp1++; lp2++; |
---|
146 | } |
---|
147 | entry(); |
---|
148 | } |
---|