]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/svm_sc8xx/flash.c
mx6sxsabresd: Add Ethernet support
[karo-tx-uboot.git] / board / svm_sc8xx / flash.c
1 /*
2  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <mpc8xx.h>
9
10 #ifndef CONFIG_ENV_ADDR
11 #define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
12 #endif
13
14 flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
15
16 /*-----------------------------------------------------------------------
17  * Functions
18  */
19 static int write_word(flash_info_t *info, ulong dest, ulong data);
20
21 #ifdef CONFIG_BOOT_8B
22 static int my_in_8(unsigned char *addr);
23 static void my_out_8(unsigned char *addr, int val);
24 #endif
25 #ifdef CONFIG_BOOT_16B
26 static int my_in_be16(unsigned short *addr);
27 static void my_out_be16(unsigned short *addr, int val);
28 #endif
29 #ifdef CONFIG_BOOT_32B
30 static unsigned my_in_be32(unsigned *addr);
31 static void my_out_be32(unsigned *addr, int val);
32 #endif
33 /*-----------------------------------------------------------------------
34  */
35
36 unsigned long flash_init(void)
37 {
38         volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
39         volatile memctl8xx_t *memctl = &immap->im_memctl;
40         unsigned long size_b0, size_b1;
41         int i;
42
43         size_b0 = 0;
44         size_b1 = 0;
45         /* Init: no FLASHes known */
46         for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i)
47                 flash_info[i].flash_id = FLASH_UNKNOWN;
48
49 #ifdef CONFIG_SYS_DOC_BASE
50 #ifndef CONFIG_FEL8xx_AT
51         /* 32k bytes */
52         memctl->memc_or5 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC);
53         memctl->memc_br5 = CONFIG_SYS_DOC_BASE | 0x401;
54 #else
55         /* 32k bytes */
56         memctl->memc_or3 = (0xffff8000 | CONFIG_SYS_OR_TIMING_DOC);
57         memctl->memc_br3 = CONFIG_SYS_DOC_BASE | 0x401;
58 #endif
59 #endif
60 #if defined(CONFIG_BOOT_8B)
61         size_b0 = 0x80000;      /* 512 K */
62
63         flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM040;
64         flash_info[0].sector_count = 8;
65         flash_info[0].size = 0x00080000;
66
67         /* set up sector start address table */
68         for (i = 0; i < flash_info[0].sector_count; i++)
69                 flash_info[0].start[i] = 0x40000000 + (i * 0x10000);
70
71         /* protect all sectors */
72         for (i = 0; i < flash_info[0].sector_count; i++)
73                 flash_info[0].protect[i] = 0x1;
74
75 #elif defined(CONFIG_BOOT_16B)
76         size_b0 = 0x400000;     /* 4MB , assume AMD29LV320B */
77
78         flash_info[0].flash_id = FLASH_MAN_AMD | FLASH_AM320B;
79         flash_info[0].sector_count = 67;
80         flash_info[0].size = 0x00400000;
81
82         /* set up sector start address table */
83         flash_info[0].start[0] = 0x40000000;
84         flash_info[0].start[1] = 0x40000000 + 0x4000;
85         flash_info[0].start[2] = 0x40000000 + 0x6000;
86         flash_info[0].start[3] = 0x40000000 + 0x8000;
87
88         for (i = 4; i < flash_info[0].sector_count; i++) {
89                 flash_info[0].start[i] =
90                         0x40000000 + 0x10000 + ((i - 4) * 0x10000);
91         }
92
93         /* protect all sectors */
94         for (i = 0; i < flash_info[0].sector_count; i++)
95                 flash_info[0].protect[i] = 0x1;
96 #endif
97
98 #ifdef CONFIG_BOOT_32B
99
100         /* Static FLASH Bank configuration here - FIXME XXX */
101         size_b0 = flash_get_size((vu_long *) FLASH_BASE0_PRELIM,
102                                &flash_info[0]);
103
104         if (flash_info[0].flash_id == FLASH_UNKNOWN) {
105                 printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
106                         size_b0, size_b0 << 20);
107         }
108
109         size_b1 = flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
110                                &flash_info[1]);
111
112         if (size_b1 > size_b0) {
113                 printf("## ERROR: "
114                         "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
115                         size_b1, size_b1 << 20, size_b0, size_b0 << 20);
116                 flash_info[0].flash_id = FLASH_UNKNOWN;
117                 flash_info[1].flash_id = FLASH_UNKNOWN;
118                 flash_info[0].sector_count = -1;
119                 flash_info[1].sector_count = -1;
120                 flash_info[0].size = 0;
121                 flash_info[1].size = 0;
122
123                 return 0;
124         }
125
126         /* Remap FLASH according to real size */
127         memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH |
128                                 (-size_b0 & OR_AM_MSK);
129         memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) |
130                                 BR_MS_GPCM | BR_V;
131
132         /* Re-do sizing to get full correct info */
133         size_b0 = flash_get_size((vu_long *) CONFIG_SYS_FLASH_BASE,
134                                 &flash_info[0]);
135
136         flash_get_offsets(CONFIG_SYS_FLASH_BASE, &flash_info[0]);
137
138 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
139         /* monitor protection ON by default */
140         flash_protect(FLAG_PROTECT_SET,
141                 CONFIG_SYS_MONITOR_BASE,
142                 CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
143                 &flash_info[0]);
144 #endif
145
146 #ifdef  CONFIG_ENV_IS_IN_FLASH
147         /* ENV protection ON by default */
148         flash_protect(FLAG_PROTECT_SET,
149                 CONFIG_ENV_ADDR,
150                 CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
151 #endif
152
153         if (size_b1) {
154                 memctl->memc_or1 = CONFIG_SYS_OR_TIMING_FLASH |
155                         (-size_b1 & 0xFFFF8000);
156                 memctl->memc_br1 = ((CONFIG_SYS_FLASH_BASE +
157                         size_b0) & BR_BA_MSK) | BR_MS_GPCM | BR_V;
158
159                 /* Re-do sizing to get full correct info */
160                 size_b1 = flash_get_size((vu_long *)(CONFIG_SYS_FLASH_BASE +
161                                         size_b0), &flash_info[1]);
162
163                 flash_get_offsets(CONFIG_SYS_FLASH_BASE + size_b0,
164                                   &flash_info[1]);
165
166 #if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
167                 /* monitor protection ON by default */
168                 flash_protect(FLAG_PROTECT_SET,
169                               CONFIG_SYS_MONITOR_BASE,
170                               CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
171                               &flash_info[1]);
172 #endif
173
174 #ifdef  CONFIG_ENV_IS_IN_FLASH
175                 /* ENV protection ON by default */
176                 flash_protect(FLAG_PROTECT_SET,
177                               CONFIG_ENV_ADDR,
178                               CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
179                               &flash_info[1]);
180 #endif
181         } else {
182                 memctl->memc_br1 = 0;   /* invalidate bank */
183
184                 flash_info[1].flash_id = FLASH_UNKNOWN;
185                 flash_info[1].sector_count = -1;
186         }
187
188         flash_info[0].size = size_b0;
189         flash_info[1].size = size_b1;
190
191
192 #endif /* CONFIG_BOOT_32B */
193
194         return size_b0 + size_b1;
195 }
196
197
198 void flash_print_info(flash_info_t *info)
199 {
200         int i;
201
202         if (info->flash_id == FLASH_UNKNOWN) {
203                 printf("missing or unknown FLASH type\n");
204                 return;
205         }
206
207         switch (info->flash_id & FLASH_VENDMASK) {
208         case FLASH_MAN_AMD:
209                 printf("AMD ");
210                 break;
211         case FLASH_MAN_FUJ:
212                 printf("FUJITSU ");
213                 break;
214         default:
215                 printf("Unknown Vendor ");
216                 break;
217         }
218
219         switch (info->flash_id & FLASH_TYPEMASK) {
220         case FLASH_AM400B:
221                 printf("AM29LV400B (4 Mbit, bottom boot sect)\n");
222                 break;
223         case FLASH_AM400T:
224                 printf("AM29LV400T (4 Mbit, top boot sector)\n");
225                 break;
226         case FLASH_AM800B:
227                 printf("AM29LV800B (8 Mbit, bottom boot sect)\n");
228                 break;
229         case FLASH_AM800T:
230                 printf("AM29LV800T (8 Mbit, top boot sector)\n");
231                 break;
232         case FLASH_AM160B:
233                 printf("AM29LV160B (16 Mbit, bottom boot sect)\n");
234                 break;
235         case FLASH_AM160T:
236                 printf("AM29LV160T (16 Mbit, top boot sector)\n");
237                 break;
238         case FLASH_AM320B:
239                 printf("AM29LV320B (32 Mbit, bottom boot sect)\n");
240                 break;
241         case FLASH_AM320T:
242                 printf("AM29LV320T (32 Mbit, top boot sector)\n");
243                 break;
244         default:
245                 printf("Unknown Chip Type\n");
246                 break;
247         }
248
249         printf("  Size: %ld MB in %d Sectors\n",
250                 info->size >> 20, info->sector_count);
251
252         printf("  Sector Start Addresses:");
253         for (i = 0; i < info->sector_count; ++i) {
254                 if ((i % 5) == 0)
255                         printf("\n   ");
256                 printf(" %08lX%s",
257                        info->start[i], info->protect[i] ? " (RO)" : "     ");
258         }
259         printf("\n");
260         return;
261 }
262
263 /*
264  * The following code cannot be run from FLASH!
265  */
266
267 int flash_erase(flash_info_t *info, int s_first, int s_last)
268 {
269         vu_long *addr = (vu_long *) (info->start[0]);
270         int flag, prot, sect, l_sect, in_mid, in_did;
271         ulong start, now, last;
272
273         if ((s_first < 0) || (s_first > s_last)) {
274                 if (info->flash_id == FLASH_UNKNOWN)
275                         printf("- missing\n");
276                 else
277                         printf("- no sectors to erase\n");
278
279                 return 1;
280         }
281
282         if ((info->flash_id == FLASH_UNKNOWN) ||
283             (info->flash_id > FLASH_AMD_COMP)) {
284                 printf("Can't erase unknown flash type %08lx - aborted\n",
285                        info->flash_id);
286                 return 1;
287         }
288
289         prot = 0;
290         for (sect = s_first; sect <= s_last; ++sect) {
291                 if (info->protect[sect])
292                         prot++;
293         }
294
295         if (prot) {
296                 printf("- Warning: %d protected sectors will not be erased!\n",
297                         prot);
298         } else {
299                 printf("\n");
300         }
301
302         l_sect = -1;
303
304         /* Disable interrupts which might cause a timeout here */
305         flag = disable_interrupts();
306
307 #if defined(CONFIG_BOOT_8B)
308         my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
309         my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
310         my_out_8((unsigned char *)((ulong)addr + 0x555), 0x90);
311
312         in_mid = my_in_8((unsigned char *)addr);
313         in_did = my_in_8((unsigned char *)((ulong)addr + 1));
314
315         printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
316
317         my_out_8((unsigned char *)addr, 0xf0);
318         udelay(1);
319
320         my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
321         my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
322         my_out_8((unsigned char *)((ulong)addr + 0x555), 0x80);
323         my_out_8((unsigned char *)((ulong)addr + 0x555), 0xaa);
324         my_out_8((unsigned char *)((ulong)addr + 0x2aa), 0x55);
325
326         /* Start erase on unprotected sectors */
327         for (sect = s_first; sect <= s_last; sect++) {
328                 if (info->protect[sect] == 0) { /* not protected */
329                         addr = (vu_long *) (info->start[sect]);
330                         /*addr[0] = 0x00300030; */
331                         my_out_8((unsigned char *)((ulong)addr), 0x30);
332                         l_sect = sect;
333                 }
334         }
335 #elif defined(CONFIG_BOOT_16B)
336         my_out_be16((unsigned short *)((ulong)addr + (0xaaa)), 0xaa);
337         my_out_be16((unsigned short *)((ulong)addr + (0x554)), 0x55);
338         my_out_be16((unsigned short *)((ulong)addr + (0xaaa)), 0x90);
339         in_mid = my_in_be16((unsigned short *)addr);
340         in_did = my_in_be16((unsigned short *)((ulong)addr + 2));
341         printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
342         my_out_be16((unsigned short *)addr, 0xf0);
343         udelay(1);
344         my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
345         my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
346         my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0x80);
347         my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
348         my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
349         /* Start erase on unprotected sectors */
350         for (sect = s_first; sect <= s_last; sect++) {
351                 if (info->protect[sect] == 0) { /* not protected */
352                         addr = (vu_long *) (info->start[sect]);
353                         my_out_be16((unsigned short *)((ulong)addr), 0x30);
354                         l_sect = sect;
355                 }
356         }
357
358 #elif defined(CONFIG_BOOT_32B)
359         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
360         my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
361         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0x90);
362
363         in_mid = my_in_be32((unsigned *)addr);
364         in_did = my_in_be32((unsigned *)((ulong)addr + 4));
365
366         printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
367
368         my_out_be32((unsigned *) addr, 0xf0);
369         udelay(1);
370
371         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
372         my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
373         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0x80);
374         my_out_be32((unsigned *)((ulong)addr + 0x1554), 0xaa);
375         my_out_be32((unsigned *)((ulong)addr + 0xaa8), 0x55);
376
377         /* Start erase on unprotected sectors */
378         for (sect = s_first; sect <= s_last; sect++) {
379                 if (info->protect[sect] == 0) { /* not protected */
380                         addr = (vu_long *) (info->start[sect]);
381                         my_out_be32((unsigned *)((ulong)addr), 0x00300030);
382                         l_sect = sect;
383                 }
384         }
385
386 #else
387 #error CONFIG_BOOT_(size)B missing.
388 #endif
389         /* re-enable interrupts if necessary */
390         if (flag)
391                 enable_interrupts();
392
393         /* wait at least 80us - let's wait 1 ms */
394         udelay(1000);
395
396         /*
397          * We wait for the last triggered sector
398          */
399         if (l_sect < 0)
400                 goto DONE;
401
402         start = get_timer(0);
403         last = start;
404         addr = (vu_long *) (info->start[l_sect]);
405 #if defined(CONFIG_BOOT_8B)
406         while ((my_in_8((unsigned char *) addr) & 0x80) != 0x80)
407 #elif defined(CONFIG_BOOT_16B)
408         while ((my_in_be16((unsigned short *) addr) & 0x0080) != 0x0080)
409 #elif defined(CONFIG_BOOT_32B)
410         while ((my_in_be32((unsigned *) addr) & 0x00800080) != 0x00800080)
411 #else
412 #error CONFIG_BOOT_(size)B missing.
413 #endif
414         {
415                 now = get_timer(start);
416                 if (now > CONFIG_SYS_FLASH_ERASE_TOUT) {
417                         printf("Timeout\n");
418                         return 1;
419                 }
420                 /* show that we're waiting */
421                 if ((now - last) > 1000) {      /* every second */
422                         putc('.');
423                         last = now;
424                 }
425         }
426 DONE:
427         /* reset to read mode */
428         addr = (volatile unsigned long *) info->start[0];
429
430 #if defined(CONFIG_BOOT_8B)
431         my_out_8((unsigned char *) addr, 0xf0);
432 #elif defined(CONFIG_BOOT_16B)
433         my_out_be16((unsigned short *) addr, 0x00f0);
434 #elif defined(CONFIG_BOOT_32B)
435         my_out_be32((unsigned *) addr, 0x00F000F0);     /* reset bank */
436 #else
437 #error CONFIG_BOOT_(size)B missing.
438 #endif
439         printf(" done\n");
440         return 0;
441 }
442
443 /*
444  * Copy memory to flash, returns:
445  * 0 - OK
446  * 1 - write timeout
447  * 2 - Flash not erased
448  */
449
450 int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
451 {
452         ulong cp, wp, data;
453         int i, l, rc;
454
455         wp = (addr & ~3);       /* get lower word aligned address */
456
457         /*
458          * handle unaligned start bytes
459          */
460         l = addr - wp;
461
462         if (l != 0) {
463                 data = 0;
464                 for (i = 0, cp = wp; i < l; ++i, ++cp)
465                         data = (data << 8) | (*(uchar *) cp);
466
467                 for (; i < 4 && cnt > 0; ++i) {
468                         data = (data << 8) | *src++;
469                         --cnt;
470                         ++cp;
471                 }
472                 for (; cnt == 0 && i < 4; ++i, ++cp)
473                         data = (data << 8) | (*(uchar *) cp);
474
475                 rc = write_word(info, wp, data);
476
477                 if (rc != 0)
478                         return rc;
479
480                 wp += 4;
481         }
482
483         /*
484          * handle word aligned part
485          */
486         while (cnt >= 4) {
487                 data = 0;
488                 for (i = 0; i < 4; ++i)
489                         data = (data << 8) | *src++;
490
491                 rc = write_word(info, wp, data);
492
493                 if (rc != 0)
494                         return rc;
495
496                 wp += 4;
497                 cnt -= 4;
498         }
499
500         if (cnt == 0)
501                 return 0;
502
503         /*
504          * handle unaligned tail bytes
505          */
506         data = 0;
507         for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
508                 data = (data << 8) | *src++;
509                 --cnt;
510         }
511         for (; i < 4; ++i, ++cp)
512                 data = (data << 8) | (*(uchar *) cp);
513
514         return write_word(info, wp, data);
515 }
516
517 /*
518  * Write a word to Flash, returns:
519  * 0 - OK
520  * 1 - write timeout
521  * 2 - Flash not erased
522  */
523 static int write_word(flash_info_t *info, ulong dest, ulong data)
524 {
525         ulong addr = (ulong) (info->start[0]);
526         ulong start;
527         int flag;
528         ulong i;
529         int data_short[2];
530
531         /* Check if Flash is (sufficiently) erased */
532         if (((ulong)*(ulong *)dest & data) != data)
533                 return 2;
534
535         /* Disable interrupts which might cause a timeout here */
536         flag = disable_interrupts();
537 #if defined(CONFIG_BOOT_8B)
538 #ifdef DEBUG
539         {
540                 int in_mid, in_did;
541
542                 my_out_8((unsigned char *) (addr + 0x555), 0xaa);
543                 my_out_8((unsigned char *) (addr + 0x2aa), 0x55);
544                 my_out_8((unsigned char *) (addr + 0x555), 0x90);
545
546                 in_mid = my_in_8((unsigned char *) addr);
547                 in_did = my_in_8((unsigned char *) (addr + 1));
548
549                 printf(" man ID=0x%x, dev ID=0x%x.\n", in_mid, in_did);
550
551                 my_out_8((unsigned char *) addr, 0xf0);
552                 udelay(1);
553         }
554 #endif
555         {
556                 int data_ch[4];
557
558                 data_ch[0] = (int) ((data >> 24) & 0xff);
559                 data_ch[1] = (int) ((data >> 16) & 0xff);
560                 data_ch[2] = (int) ((data >> 8) & 0xff);
561                 data_ch[3] = (int) (data & 0xff);
562
563                 for (i = 0; i < 4; i++) {
564                         my_out_8((unsigned char *) (addr + 0x555), 0xaa);
565                         my_out_8((unsigned char *) (addr + 0x2aa), 0x55);
566                         my_out_8((unsigned char *) (addr + 0x555), 0xa0);
567                         my_out_8((unsigned char *) (dest + i), data_ch[i]);
568
569                         /* re-enable interrupts if necessary */
570                         if (flag)
571                                 enable_interrupts();
572
573                         start = get_timer(0);
574                         while ((my_in_8((unsigned char *)(dest + i))) !=
575                                (data_ch[i])) {
576                                 if (get_timer(start) >
577                                     CONFIG_SYS_FLASH_WRITE_TOUT) {
578                                         return 1;
579                                 }
580                         }
581                 }               /* for */
582         }
583 #elif defined(CONFIG_BOOT_16B)
584         data_short[0] = (int) (data >> 16) & 0xffff;
585         data_short[1] = (int) data & 0xffff;
586         for (i = 0; i < 2; i++) {
587                 my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xaa);
588                 my_out_be16((unsigned short *)((ulong)addr + 0x554), 0x55);
589                 my_out_be16((unsigned short *)((ulong)addr + 0xaaa), 0xa0);
590                 my_out_be16((unsigned short *)(dest + (i * 2)),
591                             data_short[i]);
592
593                 /* re-enable interrupts if necessary */
594                 if (flag)
595                         enable_interrupts();
596
597                 start = get_timer(0);
598                 while ((my_in_be16((unsigned short *)(dest + (i * 2)))) !=
599                                                         (data_short[i])) {
600                         if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
601                                 return 1;
602                 }
603         }
604 #elif defined(CONFIG_BOOT_32B)
605         addr[0x0555] = 0x00AA00AA;
606         addr[0x02AA] = 0x00550055;
607         addr[0x0555] = 0x00A000A0;
608
609         *((vu_long *)dest) = data;
610
611         /* re-enable interrupts if necessary */
612         if (flag)
613                 enable_interrupts();
614
615         /* data polling for D7 */
616         start = get_timer(0);
617         while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
618                 if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
619                         return 1;
620         }
621 #endif
622         return 0;
623 }
624
625 #ifdef CONFIG_BOOT_8B
626 static int my_in_8(unsigned char *addr)
627 {
628         int ret;
629         __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
630
631         return ret;
632 }
633
634 static void my_out_8(unsigned char *addr, int val)
635 {
636         __asm__ __volatile__("stb%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
637 }
638 #endif
639 #ifdef CONFIG_BOOT_16B
640 static int my_in_be16(unsigned short *addr)
641 {
642         int ret;
643         __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
644
645         return ret;
646 }
647
648 static void my_out_be16(unsigned short *addr, int val)
649 {
650         __asm__ __volatile__("sth%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
651 }
652 #endif
653 #ifdef CONFIG_BOOT_32B
654 static unsigned my_in_be32(unsigned *addr)
655 {
656         unsigned ret;
657         __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio":"=r"(ret):"m"(*addr));
658
659         return ret;
660 }
661
662 static void my_out_be32(unsigned *addr, int val)
663 {
664         __asm__ __volatile__("stw%U0%X0 %1,%0; eieio":"=m"(*addr):"r"(val));
665 }
666 #endif