3be6feefa8a9eca9c61486dfff7a156edc6c8430
[linux-2.6.git] / arch / blackfin / mach-bf533 / head.S
1 /*
2  * File:         arch/blackfin/mach-bf533/head.S
3  * Based on:
4  * Author:       Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
5  *
6  * Created:      1998
7  * Description:  bf533 startup file
8  *
9  * Modified:
10  *               Copyright 2004-2006 Analog Devices Inc.
11  *
12  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, see the file COPYING, or write
26  * to the Free Software Foundation, Inc.,
27  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
28  */
29
30 #include <linux/linkage.h>
31 #include <linux/init.h>
32 #include <asm/blackfin.h>
33 #include <asm/trace.h>
34 #if CONFIG_BFIN_KERNEL_CLOCK
35 #include <asm/mach-common/clocks.h>
36 #include <asm/mach/mem_init.h>
37 #endif
38 #if CONFIG_DEBUG_KERNEL_START
39 #include <asm/mach-common/def_LPBlackfin.h>
40 #endif
41
42 .global __rambase
43 .global __ramstart
44 .global __ramend
45 .extern ___bss_stop
46 .extern ___bss_start
47 .extern _bf53x_relocate_l1_mem
48
49 #define INITIAL_STACK   0xFFB01000
50
51 __INIT
52
53 ENTRY(__start)
54         /* R0: argument of command line string, passed from uboot, save it */
55         R7 = R0;
56         /* Enable Cycle Counter and Nesting Of Interrupts */
57 #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
58         R0 = SYSCFG_SNEN;
59 #else
60         R0 = SYSCFG_SNEN | SYSCFG_CCEN;
61 #endif
62         SYSCFG = R0;
63         R0 = 0;
64
65         /* Clear Out All the data and pointer Registers */
66         R1 = R0;
67         R2 = R0;
68         R3 = R0;
69         R4 = R0;
70         R5 = R0;
71         R6 = R0;
72
73         P0 = R0;
74         P1 = R0;
75         P2 = R0;
76         P3 = R0;
77         P4 = R0;
78         P5 = R0;
79
80         LC0 = r0;
81         LC1 = r0;
82         L0 = r0;
83         L1 = r0;
84         L2 = r0;
85         L3 = r0;
86
87         /* Clear Out All the DAG Registers */
88         B0 = r0;
89         B1 = r0;
90         B2 = r0;
91         B3 = r0;
92
93         I0 = r0;
94         I1 = r0;
95         I2 = r0;
96         I3 = r0;
97
98         M0 = r0;
99         M1 = r0;
100         M2 = r0;
101         M3 = r0;
102
103         trace_buffer_init(p0,r0);
104         P0 = R1;
105         R0 = R1;
106
107 #if CONFIG_DEBUG_KERNEL_START
108
109 /*
110  * Set up a temporary Event Vector Table, so if something bad happens before
111  * the kernel is fully started, it doesn't vector off into the bootloaders
112  * table
113  */
114         P0.l = lo(EVT2);
115         P0.h = hi(EVT2);
116         P1.l = lo(EVT15);
117         P1.h = hi(EVT15);
118         P2.l = debug_kernel_start_trap;
119         P2.h = debug_kernel_start_trap;
120
121         RTS = P2;
122         RTI = P2;
123         RTX = P2;
124         RTN = P2;
125         RTE = P2;
126
127 .Lfill_temp_vector_table:
128         [P0++] = P2;    /* Core Event Vector Table */
129         CC = P0 == P1;
130         if !CC JUMP .Lfill_temp_vector_table
131         P0 = r0;
132         P1 = r0;
133         P2 = r0;
134
135 #endif
136
137         p0.h = hi(FIO_MASKA_C);
138         p0.l = lo(FIO_MASKA_C);
139         r0 = 0xFFFF(Z);
140         w[p0] = r0.L;   /* Disable all interrupts */
141         ssync;
142
143         p0.h = hi(FIO_MASKB_C);
144         p0.l = lo(FIO_MASKB_C);
145         r0 = 0xFFFF(Z);
146         w[p0] = r0.L;   /* Disable all interrupts */
147         ssync;
148
149         /* Turn off the icache */
150         p0.l = LO(IMEM_CONTROL);
151         p0.h = HI(IMEM_CONTROL);
152         R1 = [p0];
153         R0 = ~ENICPLB;
154         R0 = R0 & R1;
155
156         /* Anomaly 05000125 */
157 #if ANOMALY_05000125
158         CLI R2;
159         SSYNC;
160 #endif
161         [p0] = R0;
162         SSYNC;
163 #if ANOMALY_05000125
164         STI R2;
165 #endif
166
167         /* Turn off the dcache */
168         p0.l = LO(DMEM_CONTROL);
169         p0.h = HI(DMEM_CONTROL);
170         R1 = [p0];
171         R0 = ~ENDCPLB;
172         R0 = R0 & R1;
173
174         /* Anomaly 05000125 */
175 #if ANOMALY_05000125
176         CLI R2;
177         SSYNC;
178 #endif
179         [p0] = R0;
180         SSYNC;
181 #if ANOMALY_05000125
182         STI R2;
183 #endif
184
185         /* Initialise UART - when booting from u-boot, the UART is not disabled
186          * so if we dont initalize here, our serial console gets hosed */
187         p0.h = hi(UART_LCR);
188         p0.l = lo(UART_LCR);
189         r0 = 0x0(Z);
190         w[p0] = r0.L;   /* To enable DLL writes */
191         ssync;
192
193         p0.h = hi(UART_DLL);
194         p0.l = lo(UART_DLL);
195         r0 = 0x0(Z);
196         w[p0] = r0.L;
197         ssync;
198
199         p0.h = hi(UART_DLH);
200         p0.l = lo(UART_DLH);
201         r0 = 0x00(Z);
202         w[p0] = r0.L;
203         ssync;
204
205         p0.h = hi(UART_GCTL);
206         p0.l = lo(UART_GCTL);
207         r0 = 0x0(Z);
208         w[p0] = r0.L;   /* To enable UART clock */
209         ssync;
210
211         /* Initialize stack pointer */
212         sp.l = lo(INITIAL_STACK);
213         sp.h = hi(INITIAL_STACK);
214         fp = sp;
215         usp = sp;
216
217         /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
218         call _bf53x_relocate_l1_mem;
219 #if CONFIG_BFIN_KERNEL_CLOCK
220         call _start_dma_code;
221 #endif
222
223         /* Code for initializing Async memory banks */
224
225         p2.h = hi(EBIU_AMBCTL1);
226         p2.l = lo(EBIU_AMBCTL1);
227         r0.h = hi(AMBCTL1VAL);
228         r0.l = lo(AMBCTL1VAL);
229         [p2] = r0;
230         ssync;
231
232         p2.h = hi(EBIU_AMBCTL0);
233         p2.l = lo(EBIU_AMBCTL0);
234         r0.h = hi(AMBCTL0VAL);
235         r0.l = lo(AMBCTL0VAL);
236         [p2] = r0;
237         ssync;
238
239         p2.h = hi(EBIU_AMGCTL);
240         p2.l = lo(EBIU_AMGCTL);
241         r0 = AMGCTLVAL;
242         w[p2] = r0;
243         ssync;
244
245         /* This section keeps the processor in supervisor mode
246          * during kernel boot.  Switches to user mode at end of boot.
247          * See page 3-9 of Hardware Reference manual for documentation.
248          */
249
250         /* EVT15 = _real_start */
251
252         p0.l = lo(EVT15);
253         p0.h = hi(EVT15);
254         p1.l = _real_start;
255         p1.h = _real_start;
256         [p0] = p1;
257         csync;
258
259         p0.l = lo(IMASK);
260         p0.h = hi(IMASK);
261         p1.l = IMASK_IVG15;
262         p1.h = 0x0;
263         [p0] = p1;
264         csync;
265
266         raise 15;
267         p0.l = .LWAIT_HERE;
268         p0.h = .LWAIT_HERE;
269         reti = p0;
270 #if ANOMALY_05000281
271         nop; nop; nop;
272 #endif
273         rti;
274
275 .LWAIT_HERE:
276         jump .LWAIT_HERE;
277 ENDPROC(__start)
278
279 ENTRY(_real_start)
280         [ -- sp ] = reti;
281         p0.l = lo(WDOG_CTL);
282         p0.h = hi(WDOG_CTL);
283         r0 = 0xAD6(z);
284         w[p0] = r0;     /* watchdog off for now */
285         ssync;
286
287         /* Code update for BSS size == 0
288          * Zero out the bss region.
289          */
290
291         p1.l = ___bss_start;
292         p1.h = ___bss_start;
293         p2.l = ___bss_stop;
294         p2.h = ___bss_stop;
295         r0 = 0;
296         p2 -= p1;
297         lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2;
298 .L_clear_bss:
299         B[p1++] = r0;
300
301         /* In case there is a NULL pointer reference
302          * Zero out region before stext
303          */
304
305         p1.l = 0x0;
306         p1.h = 0x0;
307         r0.l = __stext;
308         r0.h = __stext;
309         r0 = r0 >> 1;
310         p2 = r0;
311         r0 = 0;
312         lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2;
313 .L_clear_zero:
314         W[p1++] = r0;
315
316         /* pass the uboot arguments to the global value command line */
317         R0 = R7;
318         call _cmdline_init;
319
320         p1.l = __rambase;
321         p1.h = __rambase;
322         r0.l = __sdata;
323         r0.h = __sdata;
324         [p1] = r0;
325
326         p1.l = __ramstart;
327         p1.h = __ramstart;
328         p3.l = ___bss_stop;
329         p3.h = ___bss_stop;
330
331         r1 = p3;
332         [p1] = r1;
333
334         /*
335          * load the current thread pointer and stack
336          */
337         r1.l = _init_thread_union;
338         r1.h = _init_thread_union;
339
340         r2.l = 0x2000;
341         r2.h = 0x0000;
342         r1 = r1 + r2;
343         sp = r1;
344         usp = sp;
345         fp = sp;
346         jump.l _start_kernel;
347 ENDPROC(_real_start)
348
349 __FINIT
350
351 .section .l1.text
352 #if CONFIG_BFIN_KERNEL_CLOCK
353 ENTRY(_start_dma_code)
354         p0.h = hi(SIC_IWR);
355         p0.l = lo(SIC_IWR);
356         r0.l = 0x1;
357         r0.h = 0x0;
358         [p0] = r0;
359         SSYNC;
360
361         /*
362          *  Set PLL_CTL
363          *   - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
364          *   - [8]     = BYPASS    : BYPASS the PLL, run CLKIN into CCLK/SCLK
365          *   - [7]     = output delay (add 200ps of delay to mem signals)
366          *   - [6]     = input delay (add 200ps of input delay to mem signals)
367          *   - [5]     = PDWN      : 1=All Clocks off
368          *   - [3]     = STOPCK    : 1=Core Clock off
369          *   - [1]     = PLL_OFF   : 1=Disable Power to PLL
370          *   - [0]     = DF        : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
371          *   all other bits set to zero
372          */
373
374         p0.h = hi(PLL_LOCKCNT);
375         p0.l = lo(PLL_LOCKCNT);
376         r0 = 0x300(Z);
377         w[p0] = r0.l;
378         ssync;
379
380         P2.H = hi(EBIU_SDGCTL);
381         P2.L = lo(EBIU_SDGCTL);
382         R0 = [P2];
383         BITSET (R0, 24);
384         [P2] = R0;
385         SSYNC;
386
387         r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
388         r0 = r0 << 9;                    /* Shift it over,                  */
389         r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
390         r0 = r1 | r0;
391         r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
392         r1 = r1 << 8;                    /* Shift it over                   */
393         r0 = r1 | r0;                    /* add them all together           */
394
395         p0.h = hi(PLL_CTL);
396         p0.l = lo(PLL_CTL);              /* Load the address                */
397         cli r2;                          /* Disable interrupts              */
398         ssync;
399         w[p0] = r0.l;                    /* Set the value                   */
400         idle;                            /* Wait for the PLL to stablize    */
401         sti r2;                          /* Enable interrupts               */
402
403 .Lcheck_again:
404         p0.h = hi(PLL_STAT);
405         p0.l = lo(PLL_STAT);
406         R0 = W[P0](Z);
407         CC = BITTST(R0,5);
408         if ! CC jump .Lcheck_again;
409
410         /* Configure SCLK & CCLK Dividers */
411         r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
412         p0.h = hi(PLL_DIV);
413         p0.l = lo(PLL_DIV);
414         w[p0] = r0.l;
415         ssync;
416
417         p0.l = lo(EBIU_SDRRC);
418         p0.h = hi(EBIU_SDRRC);
419         r0 = mem_SDRRC;
420         w[p0] = r0.l;
421         ssync;
422
423         p0.l = LO(EBIU_SDBCTL);
424         p0.h = HI(EBIU_SDBCTL);     /* SDRAM Memory Bank Control Register */
425         r0 = mem_SDBCTL;
426         w[p0] = r0.l;
427         ssync;
428
429         P2.H = hi(EBIU_SDGCTL);
430         P2.L = lo(EBIU_SDGCTL);
431         R0 = [P2];
432         BITCLR (R0, 24);
433         p0.h = hi(EBIU_SDSTAT);
434         p0.l = lo(EBIU_SDSTAT);
435         r2.l = w[p0];
436         cc = bittst(r2,3);
437         if !cc jump .Lskip;
438         NOP;
439         BITSET (R0, 23);
440 .Lskip:
441         [P2] = R0;
442         SSYNC;
443
444         R0.L = lo(mem_SDGCTL);
445         R0.H = hi(mem_SDGCTL);
446         R1 = [p2];
447         R1 = R1 | R0;
448         [P2] = R1;
449         SSYNC;
450
451         p0.h = hi(SIC_IWR);
452         p0.l = lo(SIC_IWR);
453         r0.l = lo(IWR_ENABLE_ALL);
454         r0.h = hi(IWR_ENABLE_ALL);
455         [p0] = r0;
456         SSYNC;
457
458         RTS;
459 ENDPROC(_start_dma_code)
460 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
461
462 ENTRY(_bfin_reset)
463         /* No more interrupts to be handled*/
464         CLI R6;
465         SSYNC;
466
467 #if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
468         p0.h = hi(FIO_INEN);
469         p0.l = lo(FIO_INEN);
470         r0.l = ~(1 << CONFIG_ENET_FLASH_PIN);
471         w[p0] = r0.l;
472
473         p0.h = hi(FIO_DIR);
474         p0.l = lo(FIO_DIR);
475         r0.l = (1 << CONFIG_ENET_FLASH_PIN);
476         w[p0] = r0.l;
477
478         p0.h = hi(FIO_FLAG_C);
479         p0.l = lo(FIO_FLAG_C);
480         r0.l = (1 << CONFIG_ENET_FLASH_PIN);
481         w[p0] = r0.l;
482 #endif
483
484         /* Clear the IMASK register */
485         p0.h = hi(IMASK);
486         p0.l = lo(IMASK);
487         r0 = 0x0;
488         [p0] = r0;
489
490         /* Clear the ILAT register */
491         p0.h = hi(ILAT);
492         p0.l = lo(ILAT);
493         r0 = [p0];
494         [p0] = r0;
495         SSYNC;
496
497         /* make sure SYSCR is set to use BMODE */
498         P0.h = hi(SYSCR);
499         P0.l = lo(SYSCR);
500         R0.l = 0x0;
501         W[P0] = R0.l;
502         SSYNC;
503
504         /* issue a system soft reset */
505         P1.h = hi(SWRST);
506         P1.l = lo(SWRST);
507         R1.l = 0x0007;
508         W[P1] = R1;
509         SSYNC;
510
511         /* clear system soft reset */
512         R0.l = 0x0000;
513         W[P0] = R0;
514         SSYNC;
515
516         /* issue core reset */
517         raise 1;
518
519         RTS;
520 ENDPROC(_bfin_reset)
521
522 #if CONFIG_DEBUG_KERNEL_START
523 debug_kernel_start_trap:
524         /* Set up a temp stack in L1 - SDRAM might not be working  */
525         P0.L = lo(L1_DATA_A_START + 0x100);
526         P0.H = hi(L1_DATA_A_START + 0x100);
527         SP = P0;
528
529         /* Make sure the Clocks are the way I think they should be */
530         r0 = CONFIG_VCO_MULT & 63;       /* Load the VCO multiplier         */
531         r0 = r0 << 9;                    /* Shift it over,                  */
532         r1 = CLKIN_HALF;                 /* Do we need to divide CLKIN by 2?*/
533         r0 = r1 | r0;
534         r1 = PLL_BYPASS;                 /* Bypass the PLL?                 */
535         r1 = r1 << 8;                    /* Shift it over                   */
536         r0 = r1 | r0;                    /* add them all together           */
537
538         p0.h = hi(PLL_CTL);
539         p0.l = lo(PLL_CTL);              /* Load the address                */
540         cli r2;                          /* Disable interrupts              */
541         ssync;
542         w[p0] = r0.l;                    /* Set the value                   */
543         idle;                            /* Wait for the PLL to stablize    */
544         sti r2;                          /* Enable interrupts               */
545
546 .Lcheck_again1:
547         p0.h = hi(PLL_STAT);
548         p0.l = lo(PLL_STAT);
549         R0 = W[P0](Z);
550         CC = BITTST(R0,5);
551         if ! CC jump .Lcheck_again1;
552
553         /* Configure SCLK & CCLK Dividers */
554         r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
555         p0.h = hi(PLL_DIV);
556         p0.l = lo(PLL_DIV);
557         w[p0] = r0.l;
558         ssync;
559
560         /* Make sure UART is enabled - you can never be sure */
561
562 /*
563  * Setup for console. Argument comes from the menuconfig
564  */
565
566 #ifdef CONFIG_BAUD_9600
567 #define CONSOLE_BAUD_RATE       9600
568 #elif CONFIG_BAUD_19200
569 #define CONSOLE_BAUD_RATE       19200
570 #elif CONFIG_BAUD_38400
571 #define CONSOLE_BAUD_RATE       38400
572 #elif CONFIG_BAUD_57600
573 #define CONSOLE_BAUD_RATE       57600
574 #elif CONFIG_BAUD_115200
575 #define CONSOLE_BAUD_RATE       115200
576 #endif
577
578         p0.h = hi(UART_GCTL);
579         p0.l = lo(UART_GCTL);
580         r0 = 0x00(Z);
581         w[p0] = r0.L;   /* To Turn off UART clocks */
582         ssync;
583
584         p0.h = hi(UART_LCR);
585         p0.l = lo(UART_LCR);
586         r0 = 0x83(Z);
587         w[p0] = r0.L;   /* To enable DLL writes */
588         ssync;
589
590         R1 = (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_SCLK_DIV) / (CONSOLE_BAUD_RATE * 16));
591
592         p0.h = hi(UART_DLL);
593         p0.l = lo(UART_DLL);
594         r0 = 0xFF(Z);
595         r0 = R1 & R0;
596         w[p0] = r0.L;
597         ssync;
598
599         p0.h = hi(UART_DLH);
600         p0.l = lo(UART_DLH);
601         r1 >>= 8 ;
602         w[p0] = r1.L;
603         ssync;
604
605         p0.h = hi(UART_GCTL);
606         p0.l = lo(UART_GCTL);
607         r0 = 0x0(Z);
608         w[p0] = r0.L;   /* To enable UART clock */
609         ssync;
610
611         p0.h = hi(UART_LCR);
612         p0.l = lo(UART_LCR);
613         r0 = 0x03(Z);
614         w[p0] = r0.L;   /* To Turn on UART */
615         ssync;
616
617         p0.h = hi(UART_GCTL);
618         p0.l = lo(UART_GCTL);
619         r0 = 0x01(Z);
620         w[p0] = r0.L;   /* To Turn on UART Clocks */
621         ssync;
622
623         P0.h = hi(UART_THR);
624         P0.l = lo(UART_THR);
625         P1.h = hi(UART_LSR);
626         P1.l = lo(UART_LSR);
627
628         R0.L = 'K';
629         call .Lwait_char;
630         R0.L='e';
631         call .Lwait_char;
632         R0.L='r';
633         call .Lwait_char;
634         R0.L='n'
635         call .Lwait_char;
636         R0.L='e'
637         call .Lwait_char;
638         R0.L='l';
639         call .Lwait_char;
640         R0.L=' ';
641         call .Lwait_char;
642         R0.L='c';
643         call .Lwait_char;
644         R0.L='r';
645         call .Lwait_char;
646         R0.L='a';
647         call .Lwait_char;
648         R0.L='s';
649         call .Lwait_char;
650         R0.L='h';
651         call .Lwait_char;
652         R0.L='\r';
653         call .Lwait_char;
654         R0.L='\n';
655         call .Lwait_char;
656
657         R0.L='S';
658         call .Lwait_char;
659         R0.L='E';
660         call .Lwait_char;
661         R0.L='Q'
662         call .Lwait_char;
663         R0.L='S'
664         call .Lwait_char;
665         R0.L='T';
666         call .Lwait_char;
667         R0.L='A';
668         call .Lwait_char;
669         R0.L='T';
670         call .Lwait_char;
671         R0.L='=';
672         call .Lwait_char;
673         R2 = SEQSTAT;
674         call .Ldump_reg;
675
676         R0.L=' ';
677         call .Lwait_char;
678         R0.L='R';
679         call .Lwait_char;
680         R0.L='E'
681         call .Lwait_char;
682         R0.L='T'
683         call .Lwait_char;
684         R0.L='X';
685         call .Lwait_char;
686         R0.L='=';
687         call .Lwait_char;
688         R2 = RETX;
689         call .Ldump_reg;
690
691         R0.L='\r';
692         call .Lwait_char;
693         R0.L='\n';
694         call .Lwait_char;
695
696 .Ldebug_kernel_start_trap_done:
697         JUMP    .Ldebug_kernel_start_trap_done;
698 .Ldump_reg:
699         R3 = 32;
700         R4 = 0x0F;
701         R5 = ':';  /* one past 9 */
702
703 .Ldump_reg2:
704         R0 = R2;
705         R3 += -4;
706         R0 >>>= R3;
707         R0 = R0 & R4;
708         R0 += 0x30;
709         CC = R0 <= R5;
710         if CC JUMP .Ldump_reg1;
711         R0 += 7;
712
713 .Ldump_reg1:
714         R1.l = W[P1];
715         CC = BITTST(R1, 5);
716         if !CC JUMP .Ldump_reg1;
717         W[P0] = r0;
718
719         CC = R3 == 0;
720         if !CC JUMP .Ldump_reg2
721         RTS;
722
723 .Lwait_char:
724         R1.l = W[P1];
725         CC = BITTST(R1, 5);
726         if !CC JUMP .Lwait_char;
727         W[P0] = r0;
728         RTS;
729
730 #endif  /* CONFIG_DEBUG_KERNEL_START  */
731
732 .data
733
734 /*
735  * Set up the usable of RAM stuff. Size of RAM is determined then
736  * an initial stack set up at the end.
737  */
738
739 .align 4
740 __rambase:
741 .long   0
742 __ramstart:
743 .long   0
744 __ramend:
745 .long   0