~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/netvia/netvia.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * (C) Copyright 2000
 
3
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
4
 *
 
5
 * SPDX-License-Identifier:     GPL-2.0+
 
6
 */
 
7
 
 
8
/*
 
9
 * Pantelis Antoniou, Intracom S.A., panto@intracom.gr
 
10
 * U-Boot port on NetVia board
 
11
 */
 
12
 
 
13
#include <common.h>
 
14
#include "mpc8xx.h"
 
15
 
 
16
/****************************************************************/
 
17
 
 
18
#if defined(CONFIG_NETVIA_VERSION) && CONFIG_NETVIA_VERSION >= 2
 
19
/* last value written to the external register; we cannot read back */
 
20
unsigned int last_er_val;
 
21
#endif
 
22
 
 
23
/****************************************************************/
 
24
 
 
25
/****************************************************************/
 
26
 
 
27
/* some sane bit macros */
 
28
#define _BD(_b)                         (1U << (31-(_b)))
 
29
#define _BDR(_l, _h)                    (((((1U << (31-(_l))) - 1) << 1) | 1) & ~((1U << (31-(_h))) - 1))
 
30
 
 
31
#define _BW(_b)                         (1U << (15-(_b)))
 
32
#define _BWR(_l, _h)                    (((((1U << (15-(_l))) - 1) << 1) | 1) & ~((1U << (15-(_h))) - 1))
 
33
 
 
34
#define _BB(_b)                         (1U << (7-(_b)))
 
35
#define _BBR(_l, _h)                    (((((1U << (7-(_l))) - 1) << 1) | 1) & ~((1U << (7-(_h))) - 1))
 
36
 
 
37
#define _B(_b)                          _BD(_b)
 
38
#define _BR(_l, _h)                     _BDR(_l, _h)
 
39
 
 
40
/****************************************************************/
 
41
 
 
42
#define _NOT_USED_      0xFFFFFFFF
 
43
 
 
44
/****************************************************************/
 
45
 
 
46
#define CS_0000         0x00000000
 
47
#define CS_0001         0x10000000
 
48
#define CS_0010         0x20000000
 
49
#define CS_0011         0x30000000
 
50
#define CS_0100         0x40000000
 
51
#define CS_0101         0x50000000
 
52
#define CS_0110         0x60000000
 
53
#define CS_0111         0x70000000
 
54
#define CS_1000         0x80000000
 
55
#define CS_1001         0x90000000
 
56
#define CS_1010         0xA0000000
 
57
#define CS_1011         0xB0000000
 
58
#define CS_1100         0xC0000000
 
59
#define CS_1101         0xD0000000
 
60
#define CS_1110         0xE0000000
 
61
#define CS_1111         0xF0000000
 
62
 
 
63
#define BS_0000         0x00000000
 
64
#define BS_0001         0x01000000
 
65
#define BS_0010         0x02000000
 
66
#define BS_0011         0x03000000
 
67
#define BS_0100         0x04000000
 
68
#define BS_0101         0x05000000
 
69
#define BS_0110         0x06000000
 
70
#define BS_0111         0x07000000
 
71
#define BS_1000         0x08000000
 
72
#define BS_1001         0x09000000
 
73
#define BS_1010         0x0A000000
 
74
#define BS_1011         0x0B000000
 
75
#define BS_1100         0x0C000000
 
76
#define BS_1101         0x0D000000
 
77
#define BS_1110         0x0E000000
 
78
#define BS_1111         0x0F000000
 
79
 
 
80
#define A10_AAAA        0x00000000
 
81
#define A10_AAA0        0x00200000
 
82
#define A10_AAA1        0x00300000
 
83
#define A10_000A        0x00800000
 
84
#define A10_0000        0x00A00000
 
85
#define A10_0001        0x00B00000
 
86
#define A10_111A        0x00C00000
 
87
#define A10_1110        0x00E00000
 
88
#define A10_1111        0x00F00000
 
89
 
 
90
#define RAS_0000        0x00000000
 
91
#define RAS_0001        0x00040000
 
92
#define RAS_1110        0x00080000
 
93
#define RAS_1111        0x000C0000
 
94
 
 
95
#define CAS_0000        0x00000000
 
96
#define CAS_0001        0x00010000
 
97
#define CAS_1110        0x00020000
 
98
#define CAS_1111        0x00030000
 
99
 
 
100
#define WE_0000         0x00000000
 
101
#define WE_0001         0x00004000
 
102
#define WE_1110         0x00008000
 
103
#define WE_1111         0x0000C000
 
104
 
 
105
#define GPL4_0000       0x00000000
 
106
#define GPL4_0001       0x00001000
 
107
#define GPL4_1110       0x00002000
 
108
#define GPL4_1111       0x00003000
 
109
 
 
110
#define GPL5_0000       0x00000000
 
111
#define GPL5_0001       0x00000400
 
112
#define GPL5_1110       0x00000800
 
113
#define GPL5_1111       0x00000C00
 
114
#define LOOP            0x00000080
 
115
 
 
116
#define EXEN            0x00000040
 
117
 
 
118
#define AMX_COL         0x00000000
 
119
#define AMX_ROW         0x00000020
 
120
#define AMX_MAR         0x00000030
 
121
 
 
122
#define NA              0x00000008
 
123
 
 
124
#define UTA             0x00000004
 
125
 
 
126
#define TODT            0x00000002
 
127
 
 
128
#define LAST            0x00000001
 
129
 
 
130
const uint sdram_table[0x40] = {
 
131
        /* RSS */
 
132
        CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,                   /* ACT   */
 
133
        CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,                   /* NOP   */
 
134
        CS_0000 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA,                   /* READ  */
 
135
        CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA,                   /* PALL  */
 
136
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,                         /* NOP   */
 
137
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST,     /* NOP   */
 
138
        _NOT_USED_, _NOT_USED_,
 
139
 
 
140
        /* RBS */
 
141
        CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,                   /* ACT   */
 
142
        CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,                   /* NOP   */
 
143
        CS_0001 | BS_1111 | A10_0001 | RAS_1111 | CAS_0001 | WE_1111 | AMX_COL | UTA,                   /* READ  */
 
144
        CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,                   /* NOP   */
 
145
        CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,                         /* NOP   */
 
146
        CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,                         /* NOP   */
 
147
        CS_0001 | BS_0001 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL,                         /* PALL  */
 
148
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST,           /* NOP   */
 
149
        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
 
150
        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
 
151
 
 
152
        /* WSS */
 
153
        CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,
 
154
        CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
 
155
        CS_0000 | BS_0001 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL | UTA,
 
156
        CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA | TODT | LAST,
 
157
        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
 
158
 
 
159
        /* WBS */
 
160
        CS_0001 | BS_1111 | A10_AAAA | RAS_0001 | CAS_1111 | WE_1111 | AMX_COL | UTA,                   /* ACT   */
 
161
        CS_1111 | BS_1111 | A10_0000 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,                         /* NOP   */
 
162
        CS_0001 | BS_0000 | A10_0000 | RAS_1111 | CAS_0001 | WE_0000 | AMX_COL,                         /* WRITE */
 
163
        CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,                         /* NOP   */
 
164
        CS_1111 | BS_0000 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,                         /* NOP   */
 
165
        CS_1111 | BS_0001 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,                   /* NOP   */
 
166
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA,                   /* NOP   */
 
167
        CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL | UTA,                   /* PALL  */
 
168
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | UTA | TODT | LAST,     /* NOP   */
 
169
        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
 
170
        _NOT_USED_, _NOT_USED_, _NOT_USED_,
 
171
 
 
172
        /* UPT */
 
173
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,                         /* NOP   */
 
174
        CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_0001 | WE_1111 | AMX_COL | LOOP,
 
175
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
 
176
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL,
 
177
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | LOOP,
 
178
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | LAST,
 
179
        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
 
180
        _NOT_USED_, _NOT_USED_,
 
181
 
 
182
        /* EXC */
 
183
        CS_0001 | BS_1111 | A10_1111 | RAS_0001 | CAS_1111 | WE_0001 | AMX_COL,
 
184
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1111 | AMX_COL | TODT | LAST,
 
185
 
 
186
        /* REG */
 
187
        CS_1111 | BS_1111 | A10_1111 | RAS_1111 | CAS_1111 | WE_1110 | AMX_MAR,
 
188
        CS_0001 | BS_1111 | A10_0001 | RAS_0001 | CAS_0001 | WE_0001 | AMX_MAR | TODT | LAST,
 
189
};
 
190
 
 
191
/* ------------------------------------------------------------------------- */
 
192
 
 
193
 
 
194
/*
 
195
 * Check Board Identity:
 
196
 *
 
197
 * Test ETX ID string (ETX_xxx...)
 
198
 *
 
199
 * Return 1 always.
 
200
 */
 
201
 
 
202
int checkboard(void)
 
203
{
 
204
#if !defined(CONFIG_NETVIA_VERSION) || CONFIG_NETVIA_VERSION == 1
 
205
        printf ("NETVIA v1\n");
 
206
#else
 
207
        printf ("NETVIA v2+\n");
 
208
#endif
 
209
        return (0);
 
210
}
 
211
 
 
212
/* ------------------------------------------------------------------------- */
 
213
 
 
214
/* 0xC8 = 0b11001000 , CAS3, >> 2 = 0b00 11 0 010 */
 
215
#define MAR_SDRAM_INIT          0x000000C8LU
 
216
 
 
217
#define MCR_OP(x)               ((unsigned long)((x) & 3) << (31-1))
 
218
#define MCR_OP_MASK             MCR_OP(3)
 
219
 
 
220
#define MCR_UM(x)               ((unsigned long)((x) & 1) << (31 - 8))
 
221
#define MCR_UM_MASK             MCR_UM(1)
 
222
#define MCR_UM_UPMA             MCR_UM(0)
 
223
#define MCR_UM_UPMB             MCR_UM(1)
 
224
 
 
225
#define MCR_MB(x)               ((unsigned long)((x) & 7) << (31 - 18))
 
226
#define MCR_MB_MASK             MCR_MB(7)
 
227
#define MCR_MB_CS(x)            MCR_MB(x)
 
228
 
 
229
#define MCR_MCLF(x)             ((unsigned long)((x) & 15) << (31 - 23))
 
230
#define MCR_MCLF_MASK           MCR_MCLF(15)
 
231
 
 
232
phys_size_t initdram(int board_type)
 
233
{
 
234
        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 
235
        volatile memctl8xx_t *memctl = &immap->im_memctl;
 
236
        long int size;
 
237
 
 
238
        upmconfig(UPMA, (uint *) sdram_table, sizeof(sdram_table) / sizeof(uint));
 
239
 
 
240
        /*
 
241
         * Preliminary prescaler for refresh
 
242
         */
 
243
        memctl->memc_mptpr = CONFIG_SYS_MPTPR_1BK_8K;
 
244
 
 
245
        memctl->memc_mar = MAR_SDRAM_INIT;      /* 32-bit address to be output on the address bus if AMX = 0b11 */
 
246
 
 
247
    /*
 
248
     * Map controller bank 3 to the SDRAM bank at preliminary address.
 
249
     */
 
250
        memctl->memc_or3 = CONFIG_SYS_OR3_PRELIM;
 
251
        memctl->memc_br3 = CONFIG_SYS_BR3_PRELIM;
 
252
 
 
253
        memctl->memc_mamr = CONFIG_SYS_MAMR_9COL & ~MAMR_PTAE;  /* no refresh yet */
 
254
 
 
255
        udelay(200);
 
256
 
 
257
        /* perform SDRAM initialisation sequence */
 
258
        memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(1) | MCR_MAD(0x3C); /* precharge all                        */
 
259
        udelay(1);
 
260
        memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(0) | MCR_MAD(0x30); /* refresh 16 times(0)          */
 
261
        udelay(1);
 
262
        memctl->memc_mcr = MCR_OP_RUN | MCR_UM_UPMA | MCR_MB_CS3 | MCR_MCLF(1) | MCR_MAD(0x3E); /* exception program (write mar) */
 
263
        udelay(1);
 
264
 
 
265
        memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
 
266
 
 
267
        udelay(1000);
 
268
 
 
269
        memctl->memc_mamr = CONFIG_SYS_MAMR_9COL;
 
270
 
 
271
        size = SDRAM_MAX_SIZE;
 
272
 
 
273
        udelay(10000);
 
274
 
 
275
        return (size);
 
276
}
 
277
 
 
278
/* ------------------------------------------------------------------------- */
 
279
 
 
280
int misc_init_r(void)
 
281
{
 
282
#if defined(CONFIG_NETVIA_VERSION) && CONFIG_NETVIA_VERSION >= 2
 
283
        last_er_val = 0xffffffff;
 
284
#endif
 
285
        return(0);
 
286
}
 
287
 
 
288
/* ------------------------------------------------------------------------- */
 
289
 
 
290
/* GP = general purpose, SP = special purpose (on chip peripheral) */
 
291
 
 
292
/* bits that can have a special purpose or can be configured as inputs/outputs */
 
293
#define PA_GP_INMASK    0
 
294
#define PA_GP_OUTMASK   (_BW(5) | _BWR(14, 15))
 
295
#define PA_SP_MASK      (_BW(4) | _BWR(6, 13))
 
296
#define PA_ODR_VAL      0
 
297
#define PA_GP_OUTVAL    _BW(5)
 
298
#define PA_SP_DIRVAL    0
 
299
 
 
300
#define PB_GP_INMASK    _B(28)
 
301
#define PB_GP_OUTMASK   (_BR(16, 19) | _BR(26, 27) | _BR(29, 31))
 
302
#define PB_SP_MASK      _BR(22, 25)
 
303
#define PB_ODR_VAL      0
 
304
#define PB_GP_OUTVAL    (_BR(16, 19) | _BR(26, 27) | _BR(29, 31))
 
305
#define PB_SP_DIRVAL    0
 
306
 
 
307
#if !defined(CONFIG_NETVIA_VERSION) || CONFIG_NETVIA_VERSION == 1
 
308
 
 
309
#define PC_GP_INMASK    (_BWR(5, 7) | _BWR(9, 10) | _BW(13))
 
310
#define PC_GP_OUTMASK   _BW(12)
 
311
#define PC_SP_MASK      (_BW(4) | _BW(8))
 
312
#define PC_SOVAL        0
 
313
#define PC_INTVAL       0
 
314
#define PC_GP_OUTVAL    0
 
315
#define PC_SP_DIRVAL    0
 
316
 
 
317
#define PD_GP_INMASK    0
 
318
#define PD_GP_OUTMASK   _BWR(3, 15)
 
319
#define PD_SP_MASK      0
 
320
#define PD_GP_OUTVAL    (_BW(3) | _BW(5) | _BW(7) | _BWR(8, 15))
 
321
#define PD_SP_DIRVAL    0
 
322
 
 
323
#elif CONFIG_NETVIA_VERSION >= 2
 
324
 
 
325
#define PC_GP_INMASK    (_BW(5) | _BW(7) | _BWR(9, 11) | _BWR(13, 15))
 
326
#define PC_GP_OUTMASK   (_BW(6) | _BW(12))
 
327
#define PC_SP_MASK      (_BW(4) | _BW(8))
 
328
#define PC_SOVAL        0
 
329
#define PC_INTVAL       _BW(7)
 
330
#define PC_GP_OUTVAL    (_BW(6) | _BW(12))
 
331
#define PC_SP_DIRVAL    0
 
332
 
 
333
#define PD_GP_INMASK    0
 
334
#define PD_GP_OUTMASK   _BWR(3, 15)
 
335
#define PD_SP_MASK      0
 
336
#define PD_GP_OUTVAL    (_BW(3) | _BW(5) | _BW(9) | _BW(11))
 
337
#define PD_SP_DIRVAL    0
 
338
 
 
339
#else
 
340
#error Unknown NETVIA board version.
 
341
#endif
 
342
 
 
343
int board_early_init_f(void)
 
344
{
 
345
        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 
346
        volatile iop8xx_t *ioport = &immap->im_ioport;
 
347
        volatile cpm8xx_t *cpm = &immap->im_cpm;
 
348
        volatile memctl8xx_t *memctl = &immap->im_memctl;
 
349
 
 
350
        /* DSP0 chip select */
 
351
        memctl->memc_or4 = ((0xFFFFFFFFLU & ~(DSP_SIZE - 1)) | OR_CSNT_SAM | OR_BI | OR_ACS_DIV2 | OR_SETA | OR_TRLX);
 
352
        memctl->memc_br4 = ((DSP0_BASE & BR_BA_MSK) | BR_PS_16 | BR_V);
 
353
 
 
354
        /* DSP1 chip select */
 
355
        memctl->memc_or5 = ((0xFFFFFFFFLU & ~(DSP_SIZE - 1)) | OR_CSNT_SAM | OR_BI | OR_ACS_DIV2 | OR_SETA | OR_TRLX);
 
356
        memctl->memc_br5 = ((DSP1_BASE & BR_BA_MSK) | BR_PS_16 | BR_V);
 
357
 
 
358
        /* FPGA chip select */
 
359
        memctl->memc_or6 = ((0xFFFFFFFFLU & ~(FPGA_SIZE - 1)) | OR_BI | OR_SCY_1_CLK);
 
360
        memctl->memc_br6 = ((FPGA_BASE & BR_BA_MSK) | BR_PS_8 | BR_V);
 
361
 
 
362
#if defined(CONFIG_NETVIA_VERSION) && CONFIG_NETVIA_VERSION >= 2
 
363
        /* NAND chip select */
 
364
        memctl->memc_or1 = ((0xFFFFFFFFLU & ~(NAND_SIZE - 1)) | OR_CSNT_SAM | OR_BI | OR_SCY_8_CLK | OR_EHTR | OR_TRLX);
 
365
        memctl->memc_br1 = ((NAND_BASE & BR_BA_MSK) | BR_PS_8 | BR_V);
 
366
 
 
367
        /* kill this chip select */
 
368
        memctl->memc_br2 &= ~BR_V;      /* invalid */
 
369
 
 
370
        /* external reg chip select */
 
371
        memctl->memc_or7 = ((0xFFFFFFFFLU & ~(ER_SIZE - 1)) | OR_BI | OR_SCY_4_CLK);
 
372
        memctl->memc_br7 = ((ER_BASE & BR_BA_MSK) | BR_PS_32 | BR_V);
 
373
#endif
 
374
 
 
375
        ioport->iop_padat       = PA_GP_OUTVAL;
 
376
        ioport->iop_paodr       = PA_ODR_VAL;
 
377
        ioport->iop_padir       = PA_GP_OUTMASK | PA_SP_DIRVAL;
 
378
        ioport->iop_papar       = PA_SP_MASK;
 
379
 
 
380
        cpm->cp_pbdat           = PB_GP_OUTVAL;
 
381
        cpm->cp_pbodr           = PB_ODR_VAL;
 
382
        cpm->cp_pbdir           = PB_GP_OUTMASK | PB_SP_DIRVAL;
 
383
        cpm->cp_pbpar           = PB_SP_MASK;
 
384
 
 
385
        ioport->iop_pcdat       = PC_GP_OUTVAL;
 
386
        ioport->iop_pcdir       = PC_GP_OUTMASK | PC_SP_DIRVAL;
 
387
        ioport->iop_pcso        = PC_SOVAL;
 
388
        ioport->iop_pcint       = PC_INTVAL;
 
389
        ioport->iop_pcpar       = PC_SP_MASK;
 
390
 
 
391
        ioport->iop_pddat       = PD_GP_OUTVAL;
 
392
        ioport->iop_pddir       = PD_GP_OUTMASK | PD_SP_DIRVAL;
 
393
        ioport->iop_pdpar       = PD_SP_MASK;
 
394
 
 
395
#if defined(CONFIG_NETVIA_VERSION) && CONFIG_NETVIA_VERSION >= 2
 
396
        /* external register init */
 
397
        *(volatile uint *)ER_BASE = 0xFFFFFFFF;
 
398
#endif
 
399
 
 
400
        return 0;
 
401
}