Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / build / magpie_1_1 / sboot / athos / src / athos_main.c
1 /*
2  * Copyright (c) 2000-2008 Atheros Communications, Inc., All Rights Reserved
3  *
4  * $Id: //depot/sw/branches/fusion_usb/target_firmware/magpie_fw_dev/build/magpie_1_1/sboot/athos/src/athos_main.c#1 $
5  *
6  * This file contains type definitions
7  */
8
9 /* osapi support */
10 #include "sys_cfg.h"
11 #include "athos_api.h"
12 //#include <fwd.h>
13
14 #include "regdump.h"
15
16 /* dhry mips stone test */
17 //#include "dhry.h"
18
19 /* usb support */
20 //#include "usb_defs.h"
21 //#include "usb_type.h"
22
23 /* xtensa related */
24 #include "xtensa/corebits.h"
25 #include "xtensa/tie/xt_core.h"
26
27 #include <dma_lib.h>
28 #include <hif_pci.h>
29 #include <hif_gmac.h>
30 #include <fwd.h>
31
32
33 BOOLEAN download_enable = FALSE;
34
35 /* #define ALLOCRAM_START       0x512800 */
36 /* #define ALLOCRAM_SIZE        ( SYS_RAM_SZIE - ( ALLOCRAM_START - SYS_D_RAM_REGION_0_BASE) - SYS_D_RAM_STACK_SIZE) */
37
38 #define ALLOCRAM_START       SYS_D_RAM_REGION_3_BASE
39 #define ALLOCRAM_SIZE        SYS_RAM_BLOCK_SIZE
40
41 extern unsigned int _text_start_in_rom;
42 extern unsigned int _text_start;
43 extern unsigned int _text_end;
44
45 extern unsigned int _rodata_start_in_rom;
46 extern unsigned int _lit4_start;
47 extern unsigned int _lit4_end;
48
49 /*
50  * This special table is used by Xtensa startup code to copy
51  * ROM-based data into RAM.  See Xtensa documentation or
52  * "unpack" code in ResetVector.S for details.
53  */
54 const uint32_t _rom_store_table[] = {
55     (uint32_t)&_data_start,   (uint32_t)&_data_end, (uint32_t)&_data_start_in_rom,
56     (uint32_t)&_text_start,   (uint32_t)&_text_end, (uint32_t)0xf002000,
57     (uint32_t)&_lit4_start,   (uint32_t)&_lit4_end, (uint32_t)0xf008000,
58     (uint32_t)0x00500400,   (uint32_t)0x00500940,  (uint32_t)0x004e0260,
59     0,   0,             0
60 };
61
62
63 #define ATH_DATE_STRING     __DATE__" "__TIME__
64
65
66 /*
67  * 03/09: it'll always fall into this exception if we enable this exception handler, need to do more testing, Ryan
68  */
69 void
70 Magpie_fatal_exception_handler(CPU_exception_frame_t *exc_frame)
71 {
72     struct register_dump_s dump;
73
74     dump.exc_frame              = *exc_frame; /* structure copy */
75     dump.badvaddr               = XT_RSR_EXCVADDR();
76     dump.exc_frame.xt_exccause  = XT_RSR_EXCCAUSE();
77     dump.pc                     = exc_frame->xt_pc;
78     dump.assline                = 0;
79
80     A_PRINTF("Fatal exception (%d): pc=0x%x badvaddr=0x%x dump area=0x%x\n",
81                 dump.exc_frame.xt_exccause, dump.pc, dump.badvaddr, &dump);
82     // PRINT_FAILURE_STATE();
83
84     // A_ASSFAIL(&dump); // misc module
85 }
86
87 //dummy now
88 //void app_start(void);
89
90 static int
91 athos_linkage_check(int sz, struct _A_os_linkage_check *link_check)
92 {
93     if (sz != sizeof(struct _A_os_linkage_check)) {
94         goto app_link_error;
95     }
96
97     if (link_check->version != OS_LINKAGE_VERSION) {
98         goto app_link_error;
99     }
100
101     if (link_check->table != sizeof(struct _A_magpie_indirection_table) &&
102         (link_check->table != 0)) {
103         goto app_link_error;
104     }
105
106     return 1; /* successful linkage check */
107
108 app_link_error:
109 //    A_PRINTF("athos_linkage_check failure!\n");
110     A_PUTS("-A1-\n\r");
111     return 0;
112 }
113
114
115 #ifdef SYSTEM_MODULE_INTR
116
117 /* Mask of Interrupt Level bits in Xtensa's Processor Status register */
118 #define XTENSA_PS_INTLEVEL_MASK 0xf
119
120 LOCAL uint32_t
121 athos_block_all_intrlvl(void)
122 {
123     uint32_t tmp;
124
125     /*
126      * This function doesn't actually block ALL interrupts;
127      * it leaves ERROR & WDT interrupts -- which are fatal
128      * and are at level 3 -- active.
129      */
130     asm volatile("rsil %0,2" : "=r" (tmp));
131
132     return (uint32_t)((A_UINT32)tmp & XTENSA_PS_INTLEVEL_MASK);
133 }
134
135 LOCAL void
136 athos_unblock_all_intrlvl(void)
137 {
138     unsigned int tmp;
139
140     asm volatile("rsil %0, 0" : "=r" (tmp));
141 }
142
143 LOCAL void
144 athos_restore_intrlvl(uint32_t old_intr)
145 {
146     if (old_intr == 0) {
147         athos_unblock_all_intrlvl();
148     }
149 }
150 #endif
151
152
153 static void
154 AR6002_misaligned_load_handler(CPU_exception_frame_t *exc_frame)
155 {
156     struct register_dump_s dump;
157     uint32_t *stkptr;
158
159 #if SYSTEM_MODULE_PRINT
160     A_PRINTF("misaligned_load\n\r");
161 #else
162     A_PUTS("misaligned_load\n\r");
163 #endif
164
165     dump.exc_frame = *exc_frame; /* structure copy */
166     dump.badvaddr  = XT_RSR_EXCVADDR();
167     dump.pc        = exc_frame->xt_pc;
168
169     asm volatile("mov %0,a1" : "=r" (stkptr));
170
171     /* Stores a0,a1,a2,a3 on stack; but leaves sp unchanged */
172     xthal_window_spill();
173
174         {
175         int i;
176
177 #define MAGPIE_REGDUMP_FRAMES 5
178
179         /* Walk back the stack */
180         for (i=0; i<MAGPIE_REGDUMP_FRAMES; i++) {
181             dump.exc_frame.wb[i].a0 = stkptr[-4];
182             dump.exc_frame.wb[i].a1 = stkptr[-3];
183             dump.exc_frame.wb[i].a2 = stkptr[-2];
184             dump.exc_frame.wb[i].a3 = stkptr[-1];
185             if (dump.exc_frame.wb[i].a0 == 0) {
186                 break;
187             }
188             stkptr = (uint32_t *)dump.exc_frame.wb[i].a1;
189         }
190     }
191
192     A_MISALIGNED_LOAD_HANDLER(&dump);
193
194 }
195
196 static void
197 AR6002_fatal_exception_handler(CPU_exception_frame_t *exc_frame)
198 {
199     struct register_dump_s dump;
200
201     dump.exc_frame              = *exc_frame; /* structure copy */
202     dump.badvaddr               = XT_RSR_EXCVADDR();
203     dump.exc_frame.xt_exccause  = XT_RSR_EXCCAUSE();
204     dump.pc                     = exc_frame->xt_pc;
205     dump.assline                = 0;
206
207 #if SYSTEM_MODULE_PRINT
208     A_PRINTF("Fatal exception (%d): \tpc=0x%x \n\r\tbadvaddr=0x%x \n\r\tdump area=0x%x\n",
209                 dump.exc_frame.xt_exccause, dump.pc, dump.badvaddr, &dump);
210     PRINT_FAILURE_STATE();
211  #else
212     A_PUTS("Fatal exception\n\r");
213 #endif
214
215     A_ASSFAIL(&dump);
216
217      // trigger wdt, in case hang
218 #if defined(_ROM_)     
219     //HAL_WORD_REG_WRITE(MAGPIE_REG_RST_WDT_TIMER_CTRL_ADDR, 0x03);
220     //HAL_WORD_REG_WRITE(MAGPIE_REG_RST_WDT_TIMER_ADDR, 0x10);
221         A_WDT_ENABLE();
222 #endif
223
224     while(1)
225         ;
226 }
227
228
229 typedef void (*INSTFN)(void *);
230
231 /*
232  * These are all modules that reside in ROM which are installed
233  * by default by the operating system.  Other ROM modules may
234  * be installed by the application if they are needed.
235  */
236 struct {
237     void (* install_fn)(void *);
238     void *api_tbl;
239 } basic_ROM_module_table[] =
240 {
241
242 #if SYSTEM_MODULE_MEM
243     {(INSTFN)cmnos_mem_module_install,          (void *)&A_CMN(mem)},
244 #endif
245
246 #if SYSTEM_MODULE_MISC
247     {(INSTFN)cmnos_misc_module_install,         (void *)&A_CMN(misc)},
248 #endif
249
250 #if SYSTEM_MODULE_PRINT
251     {(INSTFN)cmnos_printf_module_install,       (void *)&A_CMN(printf)},
252 #endif
253
254 #if SYSTEM_MODULE_UART
255     {(INSTFN)cmnos_uart_module_install,       (void *)&A_CMN(uart)},
256 #endif
257
258 #if SYSTEM_MODULE_USB
259     {(INSTFN)cmnos_usb_module_install,       (void *)&A_CMN(usb)},
260 #endif
261
262 #if SYSTEM_MODULE_INTR
263     {(INSTFN)cmnos_intr_module_install,       (void *)&A_CMN(intr)},
264 #endif
265
266 #if SYSTEM_MODULE_TIMER
267     {(INSTFN)cmnos_timer_module_install,       (void *)&A_CMN(timer)},
268 #endif
269
270 #if SYSTEM_MODULE_CLOCK
271     {(INSTFN)cmnos_clock_module_install,       (void *)&A_CMN(clock)},
272 #endif
273
274 #if SYSTEM_MODULE_ALLOCRAM
275     {(INSTFN)cmnos_allocram_module_install,       (void *)&A_CMN(allocram)},
276 #endif
277
278 #if SYSTEM_MODULE_ROM_PATCH
279     {(INSTFN)cmnos_romp_module_install,       (void *)&A_CMN(romp)},
280 #endif
281
282 #if SYSTEM_MODULE_WDT
283     {(INSTFN)cmnos_wdt_module_install,       (void *)&A_CMN(wdt_timer)},
284 #endif
285
286 #if SYSTEM_MODULE_EEPROM
287     {(INSTFN)cmnos_eep_module_install,       (void *)&A_CMN(eep)},
288 #endif
289     {(INSTFN)cmnos_string_module_install,        (void *)&A_CMN(string)},
290     {(INSTFN)cmnos_tasklet_module_install,        (void *)&A_CMN(tasklet)},
291     {(INSTFN)vdesc_module_install,                  (void *)&A_INDIR(vdesc)},
292     {(INSTFN)vbuf_module_install,                   (void *)&A_INDIR(vbuf)},
293     {(INSTFN)generic_hif_module_install,                   (void *)&A_INDIR(hif)},
294     {(INSTFN)buf_pool_module_install,                  (void *)&A_INDIR(buf_pool)},
295     {(INSTFN)usbfifo_module_install,                  (void *)&A_INDIR(usbfifo_api)},
296     {(INSTFN)dma_engine_module_install,             (void *)&A_INDIR(dma_engine)}, 
297     {(INSTFN)dma_lib_module_install,                (void *)&A_INDIR(dma_lib)}, 
298 };
299
300 #define BASIC_ROM_MODULE_TABLE_SZ (sizeof(basic_ROM_module_table)/sizeof(basic_ROM_module_table[0]))
301
302 void
303 generic_hif_module_install(struct hif_api *apis)
304 {
305   A_HOSTIF hostif;
306
307   hostif = A_IS_HOST_PRESENT();
308
309   switch(hostif){
310         case HIF_USB:
311           hif_usb_module_install(apis);
312       break;
313         }
314 }
315
316 void
317 athos_indirection_table_install(void)
318 {
319     unsigned int i;
320
321     /* Sanity: start with a clear table */
322     {
323         //char *tbl = (char *)_A_OS_INDIRECTION_TABLE;
324         char *tbl = (char *)_A_MAGPIE_INDIRECTION_TABLE;
325
326         //for (i=0; i<_A_OS_INDIRECTION_TABLE_SIZE; i++) {
327         for (i=0; i<_A_MAGPIE_INDIRECTION_TABLE_SIZE; i++) {
328             tbl[i] = 0;
329         }
330     }
331
332     /* Install basic ROM modules */
333     for (i=0; i<BASIC_ROM_MODULE_TABLE_SZ; i++) {
334         basic_ROM_module_table[i].install_fn(basic_ROM_module_table[i].api_tbl);
335     }
336
337         #if !defined(_ROM_)
338         DBG_MODULE_INSTALL(); // move DBG to indirection table
339         #endif
340
341     //_A_OS_INDIRECTION_TABLE->cmnos.app_start = app_start;
342     //_A_OS_INDIRECTION_TABLE->cmnos.hal_linkage_check     = athos_linkage_check;
343     //_A_MAGPIE_INDIRECTION_TABLE->cmnos.app_start = app_start;
344     _A_MAGPIE_INDIRECTION_TABLE->cmnos.hal_linkage_check     = athos_linkage_check;
345
346 //    _A_OS_INDIRECTION_TABLE->cmnos.start_bss             = &START_BSS;
347
348 #if SYSTEM_MODULE_INTR
349     /* Install a few CPU-specific functions */
350     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._get_intrenable = xthal_get_intenable;
351     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._set_intrenable = xthal_set_intenable;
352     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._get_intrpending = xthal_get_interrupt;
353     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._unblock_all_intrlvl = athos_unblock_all_intrlvl;
354     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._intr_disable = athos_block_all_intrlvl;
355     _A_MAGPIE_INDIRECTION_TABLE->cmnos.intr._intr_restore = athos_restore_intrlvl;
356 #endif
357
358     /* UNALIGNED references are used for ASSERTs */
359     (void)_xtos_set_exception_handler(EXCCAUSE_UNALIGNED, AR6002_misaligned_load_handler);
360     (void)_xtos_set_exception_handler(EXCCAUSE_LOAD_STORE_ERROR, AR6002_fatal_exception_handler);
361     (void)_xtos_set_exception_handler(EXCCAUSE_ILLEGAL, AR6002_fatal_exception_handler);
362     (void)_xtos_set_exception_handler(EXCCAUSE_INSTR_ERROR, AR6002_fatal_exception_handler);
363     (void)_xtos_set_exception_handler(EXCCAUSE_PRIVILEGED, AR6002_fatal_exception_handler);
364     (void)_xtos_set_exception_handler(EXCCAUSE_INSTR_DATA_ERROR, AR6002_fatal_exception_handler);
365     (void)_xtos_set_exception_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, AR6002_fatal_exception_handler);
366     (void)_xtos_set_exception_handler(EXCCAUSE_DIVIDE_BY_ZERO, AR6002_fatal_exception_handler);
367 }
368
369
370 #ifdef SYSTEM_MODULE_INTR
371 /*
372  * All interrupts pass through here.  Yes, it adds a
373  * bit of overhead; but it may be very helpful with
374  * debugging, ROM patching, and workarounds.
375  *
376  * NB: Assembler code that calls this loops through all
377  * pending & enabled interrupts.
378  */
379 void
380 athos_interrupt_handler(unsigned int inum, unsigned int *interrupt_frame)
381 {
382     A_INVOKE_ISR(inum);
383 }
384 #endif
385
386 void
387 athos_interrupt_init(void)
388 {
389 #ifdef SYSTEM_MODULE_INTR
390     int i;
391     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x20;
392
393     for (i=0; i<NUM_DIRECT_INTR; i++) {
394         (void)_xtos_set_interrupt_handler(i, athos_interrupt_handler);
395     }
396     
397     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x21;
398     A_INTR_INIT();
399 //    A_MC_REG_WRITE(ADDR_ERROR_CONTROL_ADDRESS, ADDR_ERROR_CONTROL_ENABLE_MASK);
400
401     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x22;
402     athos_unblock_all_intrlvl();
403 #endif
404 }
405
406
407
408 void athos_init(A_HOSTIF hif)
409 {
410
411     ///////////////////////////////////////////////////////
412     //init each module, should be put together..
413     A_CLOCK_INIT(SYSTEM_CLK);
414
415     A_UART_INIT();
416     A_PRINTF_INIT();
417
418     A_EEP_INIT();
419 }
420
421 void led_on(unsigned int bit)
422 {
423     *(unsigned long *)0x5200c = 1<<bit;
424 }
425
426 void led_off(unsigned int bit)
427 {
428     *(unsigned long *)0x52010 = 1<<bit;
429 }
430
431
432 void led_all_on() 
433 {
434     led_on(10);
435     led_on(12);
436 }
437
438 void led_all_off()
439 {
440     led_off(10);
441     led_off(12);
442 }
443
444
445 unsigned long i=0;
446 #define LED_ON_OFF_FREQ 500
447
448 void led_task()
449 {
450     i++;
451    
452     if(i==LED_ON_OFF_FREQ*1)
453         led_on(10);
454     else if (i==LED_ON_OFF_FREQ*2)
455         led_on(12);
456     else if (i==LED_ON_OFF_FREQ*3)
457         led_off(12);
458     else if (i==LED_ON_OFF_FREQ*4)
459         led_off(10);
460     else if (i==LED_ON_OFF_FREQ*5)
461         led_all_on();
462     else if (i==LED_ON_OFF_FREQ*6)
463     {
464         i=0;
465         led_all_off();
466     }
467 }
468
469
470 void bootload()
471 {
472     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0xe;
473     CURRENT_PROGRAM = (uint32_t)bootload;
474     A_PUTS("8. wait for read/read_comp.... \n\r");
475     while(1) {
476
477         /* update wdt timer */
478         //A_WDT_TASK();
479
480         /* high priority tasks */
481         A_USB_ROM_TASK();
482         
483 //        A_DBG_TASK();
484         led_task();
485
486         if( download_enable )
487             break;
488     }
489
490 }
491
492 void
493 change_magpie_clk(uint32_t  cpu_freq, uint32_t ahb_div)
494 {
495     volatile uint32_t i = 0;
496     volatile uint32_t rd_data = 0, wd_data = 0;
497
498     /* Put the PLL into reset */
499     rd_data = HAL_WORD_REG_READ(0x00050010) | (1<<1);
500     HAL_WORD_REG_WRITE(0x00050010,rd_data);
501
502     HAL_WORD_REG_WRITE(0x00056004, 0x11);
503     rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
504
505     /* Wait for the update bit to get cleared */
506     while (rd_data)
507         rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
508
509     /* Setting of the PLL */
510     if (cpu_freq== 100) wd_data = 0x142;      /* PLL 400 MHz*/
511     else if (cpu_freq== 105) wd_data = 0x152; /* PLL 420 MHz */
512     else if (cpu_freq== 110) wd_data = 0x162; /* PLL 440 MHz*/
513     else if (cpu_freq== 115) wd_data = 0x172; /* PLL 460 MHz */
514     else if (cpu_freq== 120) wd_data = 0x182; /* PLL 480 MHz */
515     else if (cpu_freq== 125) wd_data = 0x192; /* PLL 500 MHz */
516     else if (cpu_freq== 130) wd_data = 0x1a2; /* PLL 520 MHz */
517     else if (cpu_freq== 135) wd_data = 0x1b2; /* PLL 540 MHz */
518     else if (cpu_freq== 140) wd_data = 0x1c2; /* PLL 560 MHz */
519     else if (cpu_freq== 145) wd_data = 0x1d2; /* PLL 580 MHz */
520     else if (cpu_freq== 150) wd_data = 0x1e2; /* PLL 600 MHz */
521     else if (cpu_freq== 155) wd_data = 0x1f2; /* PLL 620 MHz */
522     else if (cpu_freq== 160) wd_data = 0x202; /* PLL 640 MHz */
523     else if (cpu_freq== 165) wd_data = 0x212; /* PLL 660 MHz */
524     else if (cpu_freq== 170) wd_data = 0x222; /* PLL 680 MHz */
525     else if (cpu_freq== 175) wd_data = 0x232; /* PLL 700 MHz */
526     else if (cpu_freq== 180) wd_data = 0x242; /* PLL 720 MHz */
527     else if (cpu_freq== 185) wd_data = 0x252; /* PLL 740 MHz */
528     else if (cpu_freq== 190) wd_data = 0x262; /* PLL 760 MHz */
529     else if (cpu_freq== 195) wd_data = 0x272; /* PLL 780 MHz */
530     else if (cpu_freq== 200) wd_data = 0x142; /* PLL 400 MHz */
531     else if (cpu_freq== 210) wd_data = 0x152; /* PLL 420 MHz */
532     else if (cpu_freq== 220) wd_data = 0x162; /* PLL 440 MHz */
533     else if (cpu_freq== 230) wd_data = 0x172; /* PLL 460 MHz */
534     else if (cpu_freq== 240) wd_data = 0x182; /* PLL 480 MHz */
535     else if (cpu_freq== 250) wd_data = 0x192; /* PLL 500 MHz */
536     else if (cpu_freq== 260) wd_data = 0x1a2; /* PLL 520 MHz */
537     else if (cpu_freq== 270) wd_data = 0x1b2; /* PLL 540 MHz */
538     else if (cpu_freq== 280) wd_data = 0x1c2; /* PLL 560 MHz */
539     else if (cpu_freq== 290) wd_data = 0x1d2; /* PLL 580 MHz */
540     else if (cpu_freq== 300) wd_data = 0x1e2; /* PLL 600 MHz */
541     else if (cpu_freq== 310) wd_data = 0x1f2; /* PLL 620 MHz */
542     else if (cpu_freq== 320) wd_data = 0x202; /* PLL 640 MHz */
543     else if (cpu_freq== 330) wd_data = 0x212; /* PLL 660 MHz */
544     else if (cpu_freq== 340) wd_data = 0x222; /* PLL 680 MHz */
545     else if (cpu_freq== 350) wd_data = 0x232; /* PLL 700 MHz */
546     else if (cpu_freq== 360) wd_data = 0x242; /* PLL 720 MHz */
547     else if (cpu_freq== 370) wd_data = 0x252; /* PLL 740 MHz */
548     else if (cpu_freq== 380) wd_data = 0x262; /* PLL 760 MHz */
549     else if (cpu_freq== 390) wd_data = 0x272; /* PLL 780 MHz */
550     else if (cpu_freq== 400) wd_data = 0x282; /* PLL 800 MHz */
551     else wd_data = 0x142;                     /* PLL 400 MHz*/
552
553     HAL_WORD_REG_WRITE(0x00056000, wd_data);
554
555     /* Pull CPU PLL out of Reset */
556     rd_data = HAL_WORD_REG_READ(0x00050010) & ~(1<<1);
557     HAL_WORD_REG_WRITE(0x00050010,rd_data);
558
559     /* CPU & AHB settings */
560     rd_data = HAL_WORD_REG_READ(0x00056004);
561
562     /*  > 200 Mhz CPU clock (PLL / 2) or  < 200 Mhz (PLL / 4) */
563     if (cpu_freq > 195)
564         rd_data = (rd_data & ~(0xff<<16)) | (1<<16);
565     else
566         rd_data = (rd_data & ~(0xff<<16)) | (2<<16);
567
568     /* AHB Clock, AHB_FREQ = CPU_FREQ / ahb_div */
569     switch (ahb_div) {
570     case 1:
571         rd_data = (rd_data & ~(0x3<<8) & ~(1<<4)) | 0x1;
572         break;
573     case 2:
574         rd_data = (rd_data & ~(0x3<<8) & ~(1<<4)) | (1<<8) | 0x1;
575         break;
576     case 4:
577         rd_data = (rd_data & ~(0x3<<8) & ~(1<<4)) | (2<<8) | 0x1;
578         break;
579     default:
580         rd_data = (rd_data & ~(0x3<<8) & ~(1<<4)) | (1<<8) | 0x1;
581         break;
582     }
583     
584     HAL_WORD_REG_WRITE(0x00056004, rd_data);
585     rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
586
587     while(rd_data)
588         rd_data = HAL_WORD_REG_READ(0x00056004) & 0x1;
589
590     while(i++ < 1000)
591         ;
592     
593     /* UART Setting */
594     A_UART_HWINIT((cpu_freq / ahb_div) * (1000*1000), 115200);
595
596 //    A_PRINTF("reg_read(0x56000): %p \n", HAL_WORD_REG_READ(0x00056000));
597 //    A_PRINTF("reg_read(0x56004): %p \n", HAL_WORD_REG_READ(0x00056004));
598
599     /* set the current reference clock */
600 //    A_CLOCK_INIT(cpu_freq);
601
602 }
603
604 /* 
605  * rom1.0 fix: turn off rc if no patch/eeprom exist
606 */
607 void turn_off_rc()
608 {
609     extern BOOLEAN eep_state;
610
611         // clear the cmnos_eeprom init state
612         eep_state = FALSE;
613
614     // reset the pcie_rc shift, pll and phy
615     HAL_WORD_REG_WRITE(MAGPIE_REG_RST_RESET_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR)|(BIT10|BIT9|BIT8|BIT7)));
616         
617     // reset ahb_arb of pcie_rc
618     HAL_WORD_REG_WRITE(MAGPIE_REG_AHB_ARB_ADDR, (HAL_WORD_REG_READ(MAGPIE_REG_AHB_ARB_ADDR)|BIT1));
619 }
620
621 void bootentry(void)
622 {
623     /* uint32_t reset_temp; */
624     A_HOSTIF hostif=0x0;
625     T_BOOT_TYPE rst_status;
626     T_EEP_RET retEEP;
627
628     ///////////////////////////////////
629     athos_indirection_table_install();
630
631     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x1;
632     CURRENT_PROGRAM = (uint32_t)bootentry;
633     // athos module install
634     athos_init(hostif);     // move all the athos indirection table init function to here
635
636     athos_interrupt_init(); // install all interrupt function to known state
637
638     A_WDT_DISABLE();        // make srue wdt is diable
639
640     rst_status = A_WDT_LASTBOOT(); 
641
642     // pump up flash clock to 12.5Mhz
643     HAL_WORD_REG_WRITE(0x5b01c, 0x401);
644     
645         /*
646          *
647          * 1. turn on CPU PLL, reg(0x560000), 0x305
648          * 2. pll reset reg(0x50010), 0x03
649          * 3. pll reset reg(0x50010), 0x01
650          *
651          * - after enabling CPU PLL, left the interface pll setting
652          *   be done in each interface
653          *
654          * e.g usb_init we mdid
655          * 4. usb divide reg(0x56008), 0x0808
656          * 5. clear register reg(0x50010), bit0, bit3, bit4
657          * 6. set register reg(0x50010), bit0, bit3, bit4
658          * 7. clear register reg(0x50010), bit0, bit3, bit4
659          *
660          *  - wait for 200ms for usb phy 30mhz stable -
661          *
662          * 8. usb clock up, proceed reset of things
663          */
664
665         /* reset_temp = HAL_WORD_REG_READ(MAGPIE_REG_RST_RESET_ADDR); */
666         /* A_PRINTF("reset temp is %x \n",reset_temp); */
667         /* HAL_WORD_REG_WRITE( MAGPIE_REG_RST_RESET_ADDR, 0); */
668         
669
670     /*! move the whole cpu pll setup to host interface specific 
671      *  since when bootup, we have an external clock source
672      */
673     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x2;
674
675     hostif = A_IS_HOST_PRESENT();
676
677 /*!
678  *   GPIO_FUNCTION(0x28) - config uart (sin, sout) pair, 
679  *
680  *   pci host interface will only have (GPIO1, GPIO0), other hif (usb, pcie, gmac)
681  *   will use (GPIO5, GPIO4)
682  *
683  *   BIT8 --> (9,8)
684  *   BIT7 --> (7,6)
685  *   BIT6 --> (5,4)
686  *   BIT5 --> (3,2)
687  *   BIT4 --> (1,0)
688  *   
689  */
690     {
691         HAL_WORD_REG_WRITE( MAGPIE_REG_GPIO_FUNCTION, (HAL_WORD_REG_READ(MAGPIE_REG_GPIO_FUNCTION)&(~(BIT4|BIT5|BIT6|BIT7|BIT8))) );
692         HAL_WORD_REG_WRITE( MAGPIE_REG_GPIO_FUNCTION, (HAL_WORD_REG_READ(MAGPIE_REG_GPIO_FUNCTION)|(BIT8)) );
693     }
694
695     change_magpie_clk(200, 2);
696
697     // power on self test
698     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x5;
699         A_PUTS("\n - Boot from SFLASH - \n\r");
700
701     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x9;
702
703     /*!
704      * check the host interface type,
705      */
706     DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0x15;
707     hostif = A_IS_HOST_PRESENT();
708
709     retEEP = A_EEP_IS_EXIST();
710
711     turn_off_rc();
712
713     if( hostif == HIF_USB )
714     {
715         DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0xb;
716 #if 0
717         if( retEEP == RET_SUCCESS)
718         {
719             A_EEP_INIT();
720             /* read the usb descriptor information from rom to ram */
721             read_usb_conf();
722             
723             turn_off_rc();
724         }    
725 #endif
726         A_USB_INIT();
727
728         DEBUG_SYSTEM_STATE = (DEBUG_SYSTEM_STATE&(~0xff)) | 0xd;
729         bootload();
730     }
731
732 }
733
734
735 int main(void)
736 {
737     *(unsigned long *)0x52000 = 0x7ebff;    // set bit10/bit12 output mode
738     *(unsigned long *)0x0053fff8 = 0x0;
739     
740     // for debug purpose in case we don't know where we are
741     // keep this address update, so that we could trace the where is is
742     DEBUG_SYSTEM_STATE = 0x0;
743
744     bootentry();
745
746     A_PRINTF("FLASH_READ_COMP, jump to firmware\n");
747  
748         led_on(10);
749     led_on(12);
750
751     return 0;
752 }
753