Sun Dec 1 02:52:53 2013 UTC ()
Inform compiler that the volatile assignment will terminate the function.


(joerg)
diff -r1.3 -r1.4 src/sys/arch/evbarm/stand/boot2440/main.c

cvs diff -r1.3 -r1.4 src/sys/arch/evbarm/stand/boot2440/main.c (switch to unified diff)

--- src/sys/arch/evbarm/stand/boot2440/main.c 2013/11/04 21:54:59 1.3
+++ src/sys/arch/evbarm/stand/boot2440/main.c 2013/12/01 02:52:53 1.4
@@ -1,637 +1,638 @@ @@ -1,637 +1,638 @@
1/*- 1/*-
2 * Copyright (c) 2012 The NetBSD Foundation, Inc. 2 * Copyright (c) 2012 The NetBSD Foundation, Inc.
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This code is derived from software contributed to The NetBSD Foundation 5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Paul Fleischer <paul@xpg.dk> 6 * by Paul Fleischer <paul@xpg.dk>
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE. 27 * POSSIBILITY OF SUCH DAMAGE.
28 */ 28 */
29#include <sys/types.h> 29#include <sys/types.h>
30 30
31#include <arm/armreg.h> 31#include <arm/armreg.h>
32#include <arm/s3c2xx0/s3c2440reg.h> 32#include <arm/s3c2xx0/s3c2440reg.h>
33 33
34#include <netinet/in.h> 34#include <netinet/in.h>
35#include <netinet/in_systm.h> 35#include <netinet/in_systm.h>
36 36
37#include <lib/libkern/libkern.h> 37#include <lib/libkern/libkern.h>
38#include <lib/libsa/stand.h> 38#include <lib/libsa/stand.h>
39#include <lib/libsa/loadfile.h> 39#include <lib/libsa/loadfile.h>
40#include <lib/libsa/iodesc.h> 40#include <lib/libsa/iodesc.h>
41 41
42#include <arch/evbarm/mini2440/mini2440_bootinfo.h> 42#include <arch/evbarm/mini2440/mini2440_bootinfo.h>
43 43
44#define CSR_READ(reg) \ 44#define CSR_READ(reg) \
45 *(volatile uint32_t *)(reg) 45 *(volatile uint32_t *)(reg)
46#define CSR_WRITE(reg, val) do { \ 46#define CSR_WRITE(reg, val) do { \
47 *(volatile uint32_t *)((reg)) = val; \ 47 *(volatile uint32_t *)((reg)) = val; \
48 } while (0) 48 } while (0)
49 49
50#define UART_BAUDRATE 115200 50#define UART_BAUDRATE 115200
51#define S3C2XX0_XTAL_CLK 12000000 51#define S3C2XX0_XTAL_CLK 12000000
52#define BOOTINFO_ADDR 0x31500000 52#define BOOTINFO_ADDR 0x31500000
53 53
54/* Macros to turn on/off LEDs. Numbering is 1-4. */ 54/* Macros to turn on/off LEDs. Numbering is 1-4. */
55#define LED_REG (volatile uint16_t*)(S3C2440_GPIO_BASE+GPIO_PBDAT) 55#define LED_REG (volatile uint16_t*)(S3C2440_GPIO_BASE+GPIO_PBDAT)
56#define CLEAR_LEDS() *LED_REG = *LED_REG | 0x1e0 56#define CLEAR_LEDS() *LED_REG = *LED_REG | 0x1e0
57#define LED_ON(led) *LED_REG = *LED_REG & ( ~(1<<(led+4)) & 0x1E0 ) 57#define LED_ON(led) *LED_REG = *LED_REG & ( ~(1<<(led+4)) & 0x1E0 )
58#define LED_OFF(led) *LED_REG = *LED_REG | ( ~(1<<(led+4)) & 0x1E0 ) 58#define LED_OFF(led) *LED_REG = *LED_REG | ( ~(1<<(led+4)) & 0x1E0 )
59 59
60/* Local variables */ 60/* Local variables */
61static time_t wallclock = 0; 61static time_t wallclock = 0;
62static uint32_t timer_inc_rate; 62static uint32_t timer_inc_rate;
63void *bootinfo; 63void *bootinfo;
64int bi_size; 64int bi_size;
65char *bi_next; 65char *bi_next;
66 66
67#define STR_EXPAND(tok) #tok 67#define STR_EXPAND(tok) #tok
68#define STR(tok) STR_EXPAND(tok) 68#define STR(tok) STR_EXPAND(tok)
69 69
70#if defined(DEFAULT_BOOTFILE) 70#if defined(DEFAULT_BOOTFILE)
71static char *default_boot=STR(DEFAULT_BOOTFILE); 71static char *default_boot=STR(DEFAULT_BOOTFILE);
72#else 72#else
73static char *default_boot="net:"; 73static char *default_boot="net:";
74#endif 74#endif
75 75
76time_t getsecs(); 76time_t getsecs();
77time_t getusecs(); 77time_t getusecs();
78 78
79/* Local functions */ 79/* Local functions */
80static void s3c24x0_clock_freq2(vaddr_t clkman_base, int *fclk, int *hclk, 80static void s3c24x0_clock_freq2(vaddr_t clkman_base, int *fclk, int *hclk,
81 int *pclk); 81 int *pclk);
82static void uart_init(uint32_t pclk); 82static void uart_init(uint32_t pclk);
83static void time_init(uint32_t pclk); 83static void time_init(uint32_t pclk);
84static void bi_init(void *addr); 84static void bi_init(void *addr);
85static void bi_add(void *new, int type, int size); 85static void bi_add(void *new, int type, int size);
86static void parse_mac_address(const char *str, uint8_t *enaddr); 86static void parse_mac_address(const char *str, uint8_t *enaddr);
87static void brdsetup(void); 87static void brdsetup(void);
88static void iomux(int, const char *); 88static void iomux(int, const char *);
89 89
90extern void* dm9k_init(unsigned int tag, void *macaddr); 90extern void* dm9k_init(unsigned int tag, void *macaddr);
91 91
92/* External variables */ 92/* External variables */
93extern char bootprog_name[], bootprog_rev[]; 93extern char bootprog_name[], bootprog_rev[];
94 94
95/* External functions */ 95/* External functions */
96extern void netif_match(unsigned int tag, uint8_t *macaddr); 96extern void netif_match(unsigned int tag, uint8_t *macaddr);
97/* extern int sdif_init(unsigned int tag);*/ 97/* extern int sdif_init(unsigned int tag);*/
98 98
99/* Global variables */ 99/* Global variables */
100uint32_t socmodel; 100uint32_t socmodel;
101int pclk; 101int pclk;
102struct btinfo_rootdevice bi_rdev; 102struct btinfo_rootdevice bi_rdev;
103 103
104/* This is not very flexible, as only one net device is allowed */ 104/* This is not very flexible, as only one net device is allowed */
105struct btinfo_net bi_net; 105struct btinfo_net bi_net;
106 106
107struct btinfo_bootpath bi_path; 107struct btinfo_bootpath bi_path;
108 108
109void 109void
110main(int argc, char *argv[]) 110main(int argc, char *argv[])
111{ 111{
112 int fclk, hclk; 112 int fclk, hclk;
113 int fd; 113 int fd;
114 unsigned long marks[MARK_MAX]; 114 unsigned long marks[MARK_MAX];
115 unsigned char hdr[0x26]; 115 unsigned char hdr[0x26];
116 void (*entry)(void*); 116 void (*entry)(void*);
117 unsigned elfpriv; 117 unsigned elfpriv;
118 char *bootfile; 118 char *bootfile;
119 char *bf; 119 char *bf;
120 bool kernel_loaded; 120 bool kernel_loaded;
121 uint8_t enaddr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 121 uint8_t enaddr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
122 122
123 socmodel = CSR_READ(S3C2440_GPIO_BASE + GPIO_GSTATUS1); 123 socmodel = CSR_READ(S3C2440_GPIO_BASE + GPIO_GSTATUS1);
124 124
125 brdsetup(); 125 brdsetup();
126 126
127 /* Give some indication that main() has been reached */ 127 /* Give some indication that main() has been reached */
128 CLEAR_LEDS(); 128 CLEAR_LEDS();
129 LED_ON(4); 129 LED_ON(4);
130 130
131 /* Next, we setup the clock of the S3C2440 such that we are not 131 /* Next, we setup the clock of the S3C2440 such that we are not
132 dependent on any other bootloader in this regard. 132 dependent on any other bootloader in this regard.
133 Target FCLK is 405MHz, and we assume an input crystal of 12MHz 133 Target FCLK is 405MHz, and we assume an input crystal of 12MHz
134 */ 134 */
135 *(volatile uint32_t*)(S3C2440_CLKMAN_BASE+CLKMAN_MPLLCON) = 135 *(volatile uint32_t*)(S3C2440_CLKMAN_BASE+CLKMAN_MPLLCON) =
136 ((0x7F << PLLCON_MDIV_SHIFT) & PLLCON_MDIV_MASK) | 136 ((0x7F << PLLCON_MDIV_SHIFT) & PLLCON_MDIV_MASK) |
137 ((2 << PLLCON_PDIV_SHIFT) & PLLCON_PDIV_MASK) | 137 ((2 << PLLCON_PDIV_SHIFT) & PLLCON_PDIV_MASK) |
138 ((1 << PLLCON_SDIV_SHIFT) & PLLCON_SDIV_MASK); 138 ((1 << PLLCON_SDIV_SHIFT) & PLLCON_SDIV_MASK);
139 *(volatile uint32_t*)(S3C2440_CLKMAN_BASE+CLKMAN_UPLLCON) = 139 *(volatile uint32_t*)(S3C2440_CLKMAN_BASE+CLKMAN_UPLLCON) =
140 ((0x38 << PLLCON_MDIV_SHIFT) & PLLCON_MDIV_MASK) | 140 ((0x38 << PLLCON_MDIV_SHIFT) & PLLCON_MDIV_MASK) |
141 ((2 << PLLCON_PDIV_SHIFT) & PLLCON_PDIV_MASK) | 141 ((2 << PLLCON_PDIV_SHIFT) & PLLCON_PDIV_MASK) |
142 ((2 << PLLCON_SDIV_SHIFT) & PLLCON_SDIV_MASK); 142 ((2 << PLLCON_SDIV_SHIFT) & PLLCON_SDIV_MASK);
143 143
144 LED_ON(1); 144 LED_ON(1);
145 145
146 s3c24x0_clock_freq2(S3C2440_CLKMAN_BASE, &fclk, &hclk, &pclk); 146 s3c24x0_clock_freq2(S3C2440_CLKMAN_BASE, &fclk, &hclk, &pclk);
147 147
148 uart_init(pclk); 148 uart_init(pclk);
149 time_init(pclk); 149 time_init(pclk);
150 150
151 /* Let the user know we are alive */ 151 /* Let the user know we are alive */
152 printf("\n"); 152 printf("\n");
153 printf(">> %s boot2440, revision %s\n", bootprog_name, bootprog_rev); 153 printf(">> %s boot2440, revision %s\n", bootprog_name, bootprog_rev);
154 printf("SoC model:"); 154 printf("SoC model:");
155 switch (socmodel) { 155 switch (socmodel) {
156 case 0x32440000: 156 case 0x32440000:
157 printf(" S3C2440"); break; 157 printf(" S3C2440"); break;
158 case 0x32440001: 158 case 0x32440001:
159 printf(" S3C2440A"); break; 159 printf(" S3C2440A"); break;
160 } 160 }
161 printf(" (chipid %08x)\n", socmodel); 161 printf(" (chipid %08x)\n", socmodel);
162 162
163 bootinfo = (void*) BOOTINFO_ADDR; 163 bootinfo = (void*) BOOTINFO_ADDR;
164 bi_init(bootinfo); 164 bi_init(bootinfo);
165 165
166 bi_net.devname[0] = 0; 166 bi_net.devname[0] = 0;
167 bi_path.bootpath[0] = 0; 167 bi_path.bootpath[0] = 0;
168 168
169 /* Try to get boot arguments from any previous boot-loader */ 169 /* Try to get boot arguments from any previous boot-loader */
170 { 170 {
171 struct btinfo_bootstring ba; 171 struct btinfo_bootstring ba;
172 int j, i; 172 int j, i;
173 173
174 j = 0; 174 j = 0;
175 for (i = 0; i < argc; i++) { 175 for (i = 0; i < argc; i++) {
176 if (j == MAX_BOOT_STRING-1) { 176 if (j == MAX_BOOT_STRING-1) {
177 ba.bootstring[j] = '\0'; 177 ba.bootstring[j] = '\0';
178 continue; 178 continue;
179 } 179 }
180 if (strncmp(argv[i], "mac=", 4) == 0) { 180 if (strncmp(argv[i], "mac=", 4) == 0) {
181 parse_mac_address(argv[i]+4, enaddr); 181 parse_mac_address(argv[i]+4, enaddr);
182 } else { 182 } else {
183 if (j != 0) 183 if (j != 0)
184 ba.bootstring[j++] = ' '; 184 ba.bootstring[j++] = ' ';
185 185
186 strncpy(ba.bootstring+j, argv[i], MAX_BOOT_STRING-j); 186 strncpy(ba.bootstring+j, argv[i], MAX_BOOT_STRING-j);
187 j += strlen(argv[i]); 187 j += strlen(argv[i]);
188 } 188 }
189 } 189 }
190 bi_add(&ba, BTINFO_BOOTSTRING, sizeof(ba)); 190 bi_add(&ba, BTINFO_BOOTSTRING, sizeof(ba));
191 } 191 }
192 192
193 LED_ON(3); 193 LED_ON(3);
194 194
195 if (argc > 1) { 195 if (argc > 1) {
196 bf = argv[argc-1]; 196 bf = argv[argc-1];
197 } else { 197 } else {
198 bf = default_boot; 198 bf = default_boot;
199 } 199 }
200 200
201 /* Detect networking devices */ 201 /* Detect networking devices */
202 netif_match(0, enaddr); 202 netif_match(0, enaddr);
203 203
204 kernel_loaded = FALSE; 204 kernel_loaded = FALSE;
205 do { 205 do {
206 bootfile = strsep(&bf, ";"); 206 bootfile = strsep(&bf, ";");
207 printf("Trying \"%s\"...\n", bootfile); 207 printf("Trying \"%s\"...\n", bootfile);
208 fd = open(bootfile, 0); 208 fd = open(bootfile, 0);
209 if (fd < 0) { 209 if (fd < 0) {
210 printf("Failed: %d\n", errno); 210 printf("Failed: %d\n", errno);
211 close(fd); 211 close(fd);
212 continue; 212 continue;
213 } 213 }
214 214
215 if (fdloadfile(fd, marks, LOAD_ALL) == 0) { 215 if (fdloadfile(fd, marks, LOAD_ALL) == 0) {
216 kernel_loaded = TRUE; 216 kernel_loaded = TRUE;
217 break; 217 break;
218 } 218 }
219 } while(bf != NULL); 219 } while(bf != NULL);
220 220
221 if (!kernel_loaded) { 221 if (!kernel_loaded) {
222 panic("Failed to load kernel\n"); 222 panic("Failed to load kernel\n");
223 _rtt(); 223 _rtt();
224 } 224 }
225 225
226#if 1 226#if 1
227 /* Set MAC address of the 'dme' net device, if 227 /* Set MAC address of the 'dme' net device, if
228 * it isn't set already */ 228 * it isn't set already */
229 if (bi_net.devname[0] == 0) { 229 if (bi_net.devname[0] == 0) {
230 uint8_t en[6] = {DM9000MAC}; 230 uint8_t en[6] = {DM9000MAC};
231 snprintf(bi_net.devname, sizeof(bi_net.devname), "dme"); 231 snprintf(bi_net.devname, sizeof(bi_net.devname), "dme");
232 bi_net.cookie = 0; 232 bi_net.cookie = 0;
233 233
234 memcpy(bi_net.mac_address, en, sizeof(bi_net.mac_address)); 234 memcpy(bi_net.mac_address, en, sizeof(bi_net.mac_address));
235 } 235 }
236#endif 236#endif
237 /* 237 /*
238 * ARM ELF header has a distinctive value in "private flags" 238 * ARM ELF header has a distinctive value in "private flags"
239 * field of offset [0x24:25]; 239 * field of offset [0x24:25];
240 * - NetBSD 02 06 240 * - NetBSD 02 06
241 * - Linux 02 00 (2.4) or 02 02 (2.6) 241 * - Linux 02 00 (2.4) or 02 02 (2.6)
242 */ 242 */
243 lseek(fd, (off_t)0, SEEK_SET); 243 lseek(fd, (off_t)0, SEEK_SET);
244 read(fd, &hdr, sizeof(hdr)); 244 read(fd, &hdr, sizeof(hdr));
245 memcpy(&elfpriv, &hdr[0x24], sizeof(elfpriv)); 245 memcpy(&elfpriv, &hdr[0x24], sizeof(elfpriv));
246 246
247 entry = (void *)marks[MARK_ENTRY]; 247 entry = (void *)marks[MARK_ENTRY];
248 if (elfpriv == 0x0602) { 248 if (elfpriv == 0x0602) {
249 struct btinfo_symtab bi_syms; 249 struct btinfo_symtab bi_syms;
250 250
251 bi_syms.nsym = marks[MARK_NSYM]; 251 bi_syms.nsym = marks[MARK_NSYM];
252 bi_syms.ssym = (void*)marks[MARK_SYM]; 252 bi_syms.ssym = (void*)marks[MARK_SYM];
253 bi_syms.esym = (void*)marks[MARK_END]; 253 bi_syms.esym = (void*)marks[MARK_END];
254 bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms)); 254 bi_add(&bi_syms, BTINFO_SYMTAB, sizeof(bi_syms));
255 if (bi_path.bootpath[0] != 0) 255 if (bi_path.bootpath[0] != 0)
256 bi_add(&bi_path, BTINFO_BOOTPATH, sizeof(bi_path)); 256 bi_add(&bi_path, BTINFO_BOOTPATH, sizeof(bi_path));
257 bi_add(&bi_rdev, BTINFO_ROOTDEVICE, sizeof(bi_rdev)); 257 bi_add(&bi_rdev, BTINFO_ROOTDEVICE, sizeof(bi_rdev));
258 if (bi_net.devname[0] != 0 ) 258 if (bi_net.devname[0] != 0 )
259 bi_add(&bi_net, BTINFO_NET, sizeof(bi_net)); 259 bi_add(&bi_net, BTINFO_NET, sizeof(bi_net));
260 } else { 260 } else {
261 printf("Loaded object is not NetBSD ARM ELF"); 261 printf("Loaded object is not NetBSD ARM ELF");
262 _rtt(); 262 _rtt();
263 } 263 }
264 264
265 printf("entry=%p, nsym=%lu, ssym=%p, esym=%p\n", 265 printf("entry=%p, nsym=%lu, ssym=%p, esym=%p\n",
266 (void *)marks[MARK_ENTRY], 266 (void *)marks[MARK_ENTRY],
267 marks[MARK_NSYM], 267 marks[MARK_NSYM],
268 (void *)marks[MARK_SYM], 268 (void *)marks[MARK_SYM],
269 (void *)marks[MARK_END]); 269 (void *)marks[MARK_END]);
270 (*entry)(bootinfo); 270 (*entry)(bootinfo);
271 271
272 printf("exec returned, restarting...\n"); 272 printf("exec returned, restarting...\n");
273 _rtt(); 273 _rtt();
274} 274}
275 275
276void 276void
277uart_init(uint32_t pclk) 277uart_init(uint32_t pclk)
278{ 278{
279 /* Setup UART0 clocking: Use PCLK */ 279 /* Setup UART0 clocking: Use PCLK */
280 *(volatile uint32_t*)(S3C2440_UART_BASE(0)+SSCOM_UBRDIV) = 280 *(volatile uint32_t*)(S3C2440_UART_BASE(0)+SSCOM_UBRDIV) =
281 (pclk/(UART_BAUDRATE*16)) - 1; 281 (pclk/(UART_BAUDRATE*16)) - 1;
282 282
283 *(volatile uint32_t*)(S3C2440_UART_BASE(0)+SSCOM_UCON) = 283 *(volatile uint32_t*)(S3C2440_UART_BASE(0)+SSCOM_UCON) =
284 UCON_TXMODE_INT | UCON_RXMODE_INT; 284 UCON_TXMODE_INT | UCON_RXMODE_INT;
285 285
286 *(volatile uint32_t*)(S3C2440_UART_BASE(0)+SSCOM_ULCON) = 286 *(volatile uint32_t*)(S3C2440_UART_BASE(0)+SSCOM_ULCON) =
287 ULCON_PARITY_NONE | ULCON_LENGTH_8; 287 ULCON_PARITY_NONE | ULCON_LENGTH_8;
288 288
289 *(volatile uint32_t*)(S3C2440_UART_BASE(0)+SSCOM_UFCON) = 289 *(volatile uint32_t*)(S3C2440_UART_BASE(0)+SSCOM_UFCON) =
290 UFCON_TXTRIGGER_0 | UFCON_TXFIFO_RESET | UFCON_FIFO_ENABLE; 290 UFCON_TXTRIGGER_0 | UFCON_TXFIFO_RESET | UFCON_FIFO_ENABLE;
291} 291}
292 292
293static uint32_t countdown_duration; 293static uint32_t countdown_duration;
294 294
295static 295static
296void time_init(uint32_t pclk) 296void time_init(uint32_t pclk)
297{ 297{
298 /* Configure timer0 to be as slow as possible: 298 /* Configure timer0 to be as slow as possible:
299 Prescaler = 255 299 Prescaler = 255
300 Divider = 16 300 Divider = 16
301 */ 301 */
302 302
303 /* First, configure the prescaler */ 303 /* First, configure the prescaler */
304 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCFG0) = 0xff; 304 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCFG0) = 0xff;
305 305
306 /* Next, the divider */ 306 /* Next, the divider */
307 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCFG1) |= 307 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCFG1) |=
308 (TCFG1_MUX_DIV16 <<TCFG1_MUX_SHIFT(0)) & TCFG1_MUX_MASK(0); 308 (TCFG1_MUX_DIV16 <<TCFG1_MUX_SHIFT(0)) & TCFG1_MUX_MASK(0);
309 309
310 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) = 310 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) =
311 TCON_MANUALUPDATE(0); 311 TCON_MANUALUPDATE(0);
312 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTB(0)) = 312 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTB(0)) =
313 0xffff; 313 0xffff;
314 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) = 314 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) =
315 TCON_START(0); 315 TCON_START(0);
316 316
317 317
318 /* Timer count down duration */ 318 /* Timer count down duration */
319 countdown_duration = 65535/(pclk/256/16); 319 countdown_duration = 65535/(pclk/256/16);
320 timer_inc_rate = pclk/256/16; 320 timer_inc_rate = pclk/256/16;
321 // printf("Countdown duration is: %ds\n", countdown_duration); 321 // printf("Countdown duration is: %ds\n", countdown_duration);
322#if 0 322#if 0
323 { 323 {
324 /* Timer test */ 324 /* Timer test */
325 time_t time, old_time; 325 time_t time, old_time;
326 326
327 while(1) { 327 while(1) {
328 time = old_time = getsecs(); 328 time = old_time = getsecs();
329 do { 329 do {
330 time = getsecs(); 330 time = getsecs();
331 } while(time == old_time); 331 } while(time == old_time);
332 printf("Count %u\n", (int)time); 332 printf("Count %u\n", (int)time);
333 } 333 }
334 } 334 }
335#endif 335#endif
336} 336}
337 337
338time_t 338time_t
339getsecs() 339getsecs()
340{ 340{
341 time_t secs = getusecs()/1000000; 341 time_t secs = getusecs()/1000000;
342 return secs; 342 return secs;
343} 343}
344 344
345time_t 345time_t
346getusecs() { 346getusecs() {
347 uint32_t count; 347 uint32_t count;
348 //do { 348 //do {
349 count = *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTO(0)); 349 count = *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTO(0));
350//} while( count > 65500); 350//} while( count > 65500);
351 351
352 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) = 352 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) =
353 TCON_MANUALUPDATE(0); 353 TCON_MANUALUPDATE(0);
354 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTB(0)) = 354 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTB(0)) =
355 0xffff; 355 0xffff;
356 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) = 356 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) =
357 TCON_START(0); 357 TCON_START(0);
358 358
359 wallclock += ((65535-count)*1000000) / timer_inc_rate; 359 wallclock += ((65535-count)*1000000) / timer_inc_rate;
360 360
361 return wallclock; 361 return wallclock;
362} 362}
363 363
364void 364void
365usleep(int us) { 365usleep(int us) {
366 uint32_t count; 366 uint32_t count;
367 uint32_t target_clock = wallclock+us; 367 uint32_t target_clock = wallclock+us;
368 368
369 while( wallclock < target_clock) { 369 while( wallclock < target_clock) {
370 do { 370 do {
371 count = *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTO(0)); 371 count = *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTO(0));
372 } while( count > 65500); 372 } while( count > 65500);
373 373
374 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) = 374 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) =
375 TCON_MANUALUPDATE(0); 375 TCON_MANUALUPDATE(0);
376 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTB(0)) = 376 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCNTB(0)) =
377 0xffff; 377 0xffff;
378 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) = 378 *(volatile uint32_t*)(S3C2440_TIMER_BASE+TIMER_TCON) =
379 TCON_START(0); 379 TCON_START(0);
380 380
381 wallclock += ((65535-count)*1000000) / timer_inc_rate; 381 wallclock += ((65535-count)*1000000) / timer_inc_rate;
382 } 382 }
383} 383}
384 384
385 385
386void 386void
387mini2440_panic() 387mini2440_panic()
388{ 388{
389 int i, l; 389 int i, l;
390 int v; 390 int v;
391 while(1) { 391 while(1) {
392 CLEAR_LEDS(); 392 CLEAR_LEDS();
393 for(l=0; l<0xffffff; l++) { 393 for(l=0; l<0xffffff; l++) {
394 v = *((int*)(S3C2440_TIMER_BASE+TIMER_TCNTO(0))); 394 v = *((int*)(S3C2440_TIMER_BASE+TIMER_TCNTO(0)));
395 } 395 }
396 for(i=1; i<=4; i++) { 396 for(i=1; i<=4; i++) {
397 LED_ON(i); 397 LED_ON(i);
398 } 398 }
399 for(l=0; l<0xffffff; l++) { 399 for(l=0; l<0xffffff; l++) {
400 v = *((int*)(S3C2440_TIMER_BASE+TIMER_TCNTO(0))); 400 v = *((int*)(S3C2440_TIMER_BASE+TIMER_TCNTO(0)));
401 } 401 }
402 __USE(v); 402 __USE(v);
403 } 403 }
404} 404}
405 405
406void 406void
407s3c24x0_clock_freq2(vaddr_t clkman_base, int *fclk, int *hclk, int *pclk) 407s3c24x0_clock_freq2(vaddr_t clkman_base, int *fclk, int *hclk, int *pclk)
408{ 408{
409 uint32_t pllcon, divn, camdivn; 409 uint32_t pllcon, divn, camdivn;
410 int mdiv, pdiv, sdiv; 410 int mdiv, pdiv, sdiv;
411 uint32_t f, h, p; 411 uint32_t f, h, p;
412 412
413 pllcon = *(volatile uint32_t *)(clkman_base + CLKMAN_MPLLCON); 413 pllcon = *(volatile uint32_t *)(clkman_base + CLKMAN_MPLLCON);
414 divn = *(volatile uint32_t *)(clkman_base + CLKMAN_CLKDIVN); 414 divn = *(volatile uint32_t *)(clkman_base + CLKMAN_CLKDIVN);
415 camdivn = *(volatile uint32_t *)(clkman_base + CLKMAN_CAMDIVN); 415 camdivn = *(volatile uint32_t *)(clkman_base + CLKMAN_CAMDIVN);
416 416
417 mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT; 417 mdiv = (pllcon & PLLCON_MDIV_MASK) >> PLLCON_MDIV_SHIFT;
418 pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT; 418 pdiv = (pllcon & PLLCON_PDIV_MASK) >> PLLCON_PDIV_SHIFT;
419 sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT; 419 sdiv = (pllcon & PLLCON_SDIV_MASK) >> PLLCON_SDIV_SHIFT;
420 420
421 f = ((mdiv + 8) * S3C2XX0_XTAL_CLK) / ((pdiv + 2) * (1 << sdiv)) * 2; 421 f = ((mdiv + 8) * S3C2XX0_XTAL_CLK) / ((pdiv + 2) * (1 << sdiv)) * 2;
422 h = f; 422 h = f;
423 423
424 /* HDIVN of CLKDIVN can have 4 distinct values */ 424 /* HDIVN of CLKDIVN can have 4 distinct values */
425 switch( (divn & CLKDIVN_HDIVN_MASK) >> CLKDIVN_HDIVN_SHIFT ) 425 switch( (divn & CLKDIVN_HDIVN_MASK) >> CLKDIVN_HDIVN_SHIFT )
426 { 426 {
427 case 0: 427 case 0:
428 /* 00b: HCLK = FCLK/1*/ 428 /* 00b: HCLK = FCLK/1*/
429 break; 429 break;
430 case 1: 430 case 1:
431 /* 01b: HCLK = FCLK/2*/ 431 /* 01b: HCLK = FCLK/2*/
432 h /= 2; 432 h /= 2;
433 break; 433 break;
434 case 2: 434 case 2:
435 /* 10b: HCLK = FCLK/4 when CAMDIVN[9] (HCLK4_HALF) = 0 435 /* 10b: HCLK = FCLK/4 when CAMDIVN[9] (HCLK4_HALF) = 0
436 * HCLK = FCLK/8 when CAMDIVN[9] (HCLK4_HALF) = 1 */ 436 * HCLK = FCLK/8 when CAMDIVN[9] (HCLK4_HALF) = 1 */
437 if( camdivn & CLKCAMDIVN_HCLK4_HALF ) 437 if( camdivn & CLKCAMDIVN_HCLK4_HALF )
438 h /= 8; 438 h /= 8;
439 else 439 else
440 h /= 4; 440 h /= 4;
441 break; 441 break;
442 case 3: 442 case 3:
443 /* 11b: HCLK = FCLK/3 when CAMDIVN[8] (HCLK3_HALF) = 0 443 /* 11b: HCLK = FCLK/3 when CAMDIVN[8] (HCLK3_HALF) = 0
444 * HCLK = FCLK/6 when CAMDIVN[8] (HCLK3_HALF) = 1 */ 444 * HCLK = FCLK/6 when CAMDIVN[8] (HCLK3_HALF) = 1 */
445 if( camdivn & CLKCAMDIVN_HCLK3_HALF ) 445 if( camdivn & CLKCAMDIVN_HCLK3_HALF )
446 h /= 6; 446 h /= 6;
447 else 447 else
448 h /= 3; 448 h /= 3;
449 break; 449 break;
450 } 450 }
451 451
452 p = h; 452 p = h;
453 453
454 if (divn & CLKDIVN_PDIVN) 454 if (divn & CLKDIVN_PDIVN)
455 p /= 2; 455 p /= 2;
456 456
457 if (fclk) *fclk = f; 457 if (fclk) *fclk = f;
458 if (hclk) *hclk = h; 458 if (hclk) *hclk = h;
459 if (pclk) *pclk = p; 459 if (pclk) *pclk = p;
460} 460}
461 461
462void 462void
463putchar(int c) 463putchar(int c)
464{ 464{
465 uint32_t stat; 465 uint32_t stat;
466 466
467 if (c == '\n') 467 if (c == '\n')
468 putchar('\r'); 468 putchar('\r');
469  469
470 do { 470 do {
471 stat = CSR_READ(S3C2440_UART_BASE(0) + SSCOM_UTRSTAT); 471 stat = CSR_READ(S3C2440_UART_BASE(0) + SSCOM_UTRSTAT);
472 } while ((stat & UTRSTAT_TXEMPTY) == 0); 472 } while ((stat & UTRSTAT_TXEMPTY) == 0);
473 473
474 CSR_WRITE(S3C2440_UART_BASE(0) + SSCOM_UTXH, c); 474 CSR_WRITE(S3C2440_UART_BASE(0) + SSCOM_UTXH, c);
475} 475}
476 476
477void 477void
478_rtt() 478_rtt()
479{ 479{
480 int cpsr_save, tmp; 480 int cpsr_save, tmp;
481 /* Disable interrupts */ 481 /* Disable interrupts */
482 __asm volatile("mrs %0, cpsr;" 482 __asm volatile("mrs %0, cpsr;"
483 "orr %1, %0, %2;" 483 "orr %1, %0, %2;"
484 "msr cpsr_c, %1;" 484 "msr cpsr_c, %1;"
485 : "=r" (cpsr_save), "=r" (tmp) 485 : "=r" (cpsr_save), "=r" (tmp)
486 : "I" (I32_bit) 486 : "I" (I32_bit)
487 ); 487 );
488 488
489 /* Disable MMU */ 489 /* Disable MMU */
490 __asm volatile("mrc p15, 0, %0, c1, c0, 0;" 490 __asm volatile("mrc p15, 0, %0, c1, c0, 0;"
491 "bic %0, %0, %1;" 491 "bic %0, %0, %1;"
492 "mcr p15, 0, %0, c1, c0, 0;" 492 "mcr p15, 0, %0, c1, c0, 0;"
493 : "=r" (tmp) 493 : "=r" (tmp)
494 : "I" (CPU_CONTROL_MMU_ENABLE) 494 : "I" (CPU_CONTROL_MMU_ENABLE)
495 ); 495 );
496 496
497 /* Configure watchdog to fire now */ 497 /* Configure watchdog to fire now */
498 *(volatile uint32_t *)(S3C2440_WDT_BASE + WDT_WTCON) = 498 *(volatile uint32_t *)(S3C2440_WDT_BASE + WDT_WTCON) =
499 (0 << WTCON_PRESCALE_SHIFT) | WTCON_ENABLE | 499 (0 << WTCON_PRESCALE_SHIFT) | WTCON_ENABLE |
500 WTCON_CLKSEL_16 | WTCON_ENRST; 500 WTCON_CLKSEL_16 | WTCON_ENRST;
 501 __builtin_unreachable();
501} 502}
502 503
503void 504void
504bi_init(void *addr) 505bi_init(void *addr)
505{ 506{
506 struct btinfo_magic bi_magic; 507 struct btinfo_magic bi_magic;
507 508
508 memset(addr, 0, BOOTINFO_MAXSIZE); 509 memset(addr, 0, BOOTINFO_MAXSIZE);
509 bi_next = (char*) addr; 510 bi_next = (char*) addr;
510 bi_size = 0; 511 bi_size = 0;
511 512
512 bi_magic.magic = BOOTINFO_MAGIC; 513 bi_magic.magic = BOOTINFO_MAGIC;
513 bi_add(&bi_magic, BTINFO_MAGIC, sizeof(bi_magic)); 514 bi_add(&bi_magic, BTINFO_MAGIC, sizeof(bi_magic));
514} 515}
515 516
516 517
517void 518void
518bi_add(void *new, int type, int size) 519bi_add(void *new, int type, int size)
519{ 520{
520 struct btinfo_common *bi; 521 struct btinfo_common *bi;
521 522
522 if (bi_size + size > BOOTINFO_MAXSIZE) 523 if (bi_size + size > BOOTINFO_MAXSIZE)
523 return; 524 return;
524 525
525 bi = new; 526 bi = new;
526 bi->next = size; 527 bi->next = size;
527 bi->type = type; 528 bi->type = type;
528 memcpy(bi_next, new, size); 529 memcpy(bi_next, new, size);
529 bi_next += size; 530 bi_next += size;
530} 531}
531 532
532static void 533static void
533parse_mac_address(const char *str, uint8_t *enaddr) 534parse_mac_address(const char *str, uint8_t *enaddr)
534{ 535{
535 int i; 536 int i;
536 char *next = (char*)str; 537 char *next = (char*)str;
537 538
538 for(i=0;i<6;i++) { 539 for(i=0;i<6;i++) {
539 str = next; 540 str = next;
540 enaddr[i] = (unsigned char)strtoll(str, &next, 16); 541 enaddr[i] = (unsigned char)strtoll(str, &next, 16);
541 if( *next == ':' ) { 542 if( *next == ':' ) {
542 next++; 543 next++;
543 } else { 544 } else {
544 break; 545 break;
545 } 546 }
546 } 547 }
547} 548}
548 549
549static void 550static void
550brdsetup(void) 551brdsetup(void)
551{ 552{
552/* 553/*
553 * MINI2440 pin usage summary 554 * MINI2440 pin usage summary
554 * 555 *
555 * B5 output LED1 control 556 * B5 output LED1 control
556 * B6 output LED2 control 557 * B6 output LED2 control
557 * B7 output LED3 control 558 * B7 output LED3 control
558 * B8 output LED4 control 559 * B8 output LED4 control
559 * G0 EINT8 K1 button 560 * G0 EINT8 K1 button
560 * G3 EINT11 K2 button 561 * G3 EINT11 K2 button
561 * G5 EINT13 K3 button 562 * G5 EINT13 K3 button
562 * G6 EINT14 K4 button 563 * G6 EINT14 K4 button
563 * G7 EINT15 K5 button 564 * G7 EINT15 K5 button
564 * G11 EINT19 K6 button 565 * G11 EINT19 K6 button
565 * F7 EINT7 DM9000 interrupt 566 * F7 EINT7 DM9000 interrupt
566 * G12 EINT20 camera interrupt 567 * G12 EINT20 camera interrupt
567 * G8 input SD card presense detect 568 * G8 input SD card presense detect
568 * H8 input SD write protect sense 569 * H8 input SD write protect sense
569 * B0 TOUT0 buzzer PWM 570 * B0 TOUT0 buzzer PWM
570 * B1 TOUT1 LCD backlight PWM 571 * B1 TOUT1 LCD backlight PWM
571 * B2 output UDA1341 audio L3MODE 572 * B2 output UDA1341 audio L3MODE
572 * B3 output UDA1341 audio L3DATA 573 * B3 output UDA1341 audio L3DATA
573 * B4 output UDA1341 audio L3LOCK 574 * B4 output UDA1341 audio L3LOCK
574 * 575 *
575 * A21, A11, G15, G14, G13: not used. 576 * A21, A11, G15, G14, G13: not used.
576 * 577 *
577 * i input sense 578 * i input sense
578 * o output control 579 * o output control
579 * 2 function 2 580 * 2 function 2
580 * 3 function 3 581 * 3 function 3
581 * 0 output control (A only) 582 * 0 output control (A only)
582 * 1 function 1 (A only) 583 * 1 function 1 (A only)
583 * ./x no function, not connected or don't-care 584 * ./x no function, not connected or don't-care
584 *  585 *
585 * A ........ .1x11111 1111x111 11111111 586 * A ........ .1x11111 1111x111 11111111
586 * B .....22o ooooooo2 587 * B .....22o ooooooo2
587 * C 22222222 22222222 588 * C 22222222 22222222
588 * D 22222222 22222222 589 * D 22222222 22222222
589 * E 22222222 22222222 590 * E 22222222 22222222
590 * F ........ 22222222 591 * F ........ 22222222
591 * G xxx2222i 22232322 592 * G xxx2222i 22232322
592 * H .....22i 22222222 593 * H .....22i 22222222
593 * J ...22222 22222222 594 * J ...22222 22222222
594 */ 595 */
595 iomux('A', "........ .1x11111 1111x111 11111111"); 596 iomux('A', "........ .1x11111 1111x111 11111111");
596 iomux('B', ".....22o ooooooo2"); 597 iomux('B', ".....22o ooooooo2");
597 iomux('C', "22222222 22222222"); 598 iomux('C', "22222222 22222222");
598 iomux('D', "22222222 22222222"); 599 iomux('D', "22222222 22222222");
599 iomux('E', "22222222 22222222"); 600 iomux('E', "22222222 22222222");
600 iomux('F', "........ 22222222"); 601 iomux('F', "........ 22222222");
601 iomux('G', "xxx2222i 22232322"); 602 iomux('G', "xxx2222i 22232322");
602 iomux('H', ".....22i 22222222"); 603 iomux('H', ".....22i 22222222");
603 iomux('J', "...22222 22222222"); 604 iomux('J', "...22222 22222222");
604 605
605 /* mask all possible external interrupt source [23:3] */ 606 /* mask all possible external interrupt source [23:3] */
606 CSR_WRITE(S3C2440_GPIO_BASE + GPIO_EINTMASK, ~0); 607 CSR_WRITE(S3C2440_GPIO_BASE + GPIO_EINTMASK, ~0);
607} 608}
608 609
609static void 610static void
610iomux(int grp, const char *cnf) 611iomux(int grp, const char *cnf)
611{ 612{
612 uint32_t con; 613 uint32_t con;
613 int sft, i, v; 614 int sft, i, v;
614 615
615 con = v = 0; 616 con = v = 0;
616 sft = (grp != 'A') ? 2 : 1; 617 sft = (grp != 'A') ? 2 : 1;
617 for (i = 0; cnf[i] != '\0'; i++) { 618 for (i = 0; cnf[i] != '\0'; i++) {
618 switch (cnf[i]) { 619 switch (cnf[i]) {
619 case 'i': 620 case 'i':
620 case '0': 621 case '0':
621 case '.': 622 case '.':
622 case 'x': 623 case 'x':
623 v = 0; break; 624 v = 0; break;
624 case 'o': 625 case 'o':
625 case '1': 626 case '1':
626 v = 1; break; 627 v = 1; break;
627 case '2': 628 case '2':
628 v = 2; break; 629 v = 2; break;
629 case '3': 630 case '3':
630 v = 3; break; 631 v = 3; break;
631 default: 632 default:
632 continue; 633 continue;
633 } 634 }
634 con = (con << sft) | v; 635 con = (con << sft) | v;
635 } 636 }
636 CSR_WRITE(S3C2440_GPIO_BASE + 0x10 * (grp - 'A'), con); 637 CSR_WRITE(S3C2440_GPIO_BASE + 0x10 * (grp - 'A'), con);
637} 638}