Root/usbboot/xburst_stage2/boothandler.c

1/*
2 * USB_BOOT Handle routines
3 *
4 * Copyright (C) 2009 Qi Hardware Inc.,
5 * Author: Xiangfu Liu <xiangfu@qi-hardware.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 3 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA
20 */
21
22#include "jz4740.h"
23#include "usb.h"
24#include "error.h"
25#include "usb_boot.h"
26#include "usb_boot_defines.h"
27#include "nandflash.h"
28#include "udc.h"
29#define dprintf(x) serial_puts(x)
30
31#define MEM_WRITE 0
32#define MEM_READ 1
33
34#define MEM_8BIT (0 << 1)
35#define MEM_16BIT (1 << 1)
36#define MEM_32BIT (2 << 1)
37
38#define MEM_WRITE8 (MEM_WRITE | MEM_8BIT)
39#define MEM_WRITE16 (MEM_WRITE | MEM_16BIT)
40#define MEM_WRITE32 (MEM_WRITE | MEM_32BIT)
41#define MEM_READ8 (MEM_READ | MEM_8BIT)
42#define MEM_READ16 (MEM_READ | MEM_16BIT)
43#define MEM_READ32 (MEM_READ | MEM_32BIT)
44
45
46
47unsigned int (*nand_query)(u8 *);
48int (*nand_init)(int bus_width, int row_cycle, int page_size, int page_per_block,
49         int,int,int,int);
50int (*nand_fini)(void);
51u32 (*nand_program)(void *context, int spage, int pages,int option);
52u32 (*nand_erase)(int blk_num, int sblk, int force);
53u32 (*nand_read)(void *buf, u32 startpage, u32 pagenum,int option);
54u32 (*nand_read_oob)(void *buf, u32 startpage, u32 pagenum);
55u32 (*nand_read_raw)(void *buf, u32 startpage, u32 pagenum,int);
56u32 (*nand_mark_bad) (int bad);
57void (*nand_enable) (unsigned int csn);
58void (*nand_disable) (unsigned int csn);
59
60struct hand Hand,*Hand_p;
61extern u32 Bulk_buf[BULK_BUF_SIZE];
62extern u16 handshake_PKT[4];
63extern udc_state;
64extern void *memset(void *s, int c, size_t count);
65extern void *memcpy(void *dest, const void *src, size_t count);
66
67u32 ret_dat;
68u32 start_addr; //program operation start address or sector
69u32 ops_length; //number of operation unit ,in byte or sector
70u32 ram_addr;
71
72void config_flash_info()
73{
74}
75
76void dump_data(unsigned int *p, int size)
77{
78    int i;
79    for(i = 0; i < size; i ++)
80        serial_put_hex(*p++);
81}
82
83void config_hand()
84{
85    struct hand *hand_p;
86    hand_p=(struct hand *)Bulk_buf;
87    memcpy(&Hand, (unsigned char *)Bulk_buf, sizeof(struct hand));
88
89#if 0
90    Hand.nand_bw=hand_p->nand_bw;
91    Hand.nand_rc=hand_p->nand_rc;
92    Hand.nand_ps=hand_p->nand_ps;
93    Hand.nand_ppb=hand_p->nand_ppb;
94    Hand.nand_force_erase=hand_p->nand_force_erase;
95    Hand.nand_pn=hand_p->nand_pn;
96    Hand.nand_os=hand_p->nand_os;
97
98    Hand.nand_eccpos=hand_p->nand_eccpos;
99    Hand.nand_bbpos=hand_p->nand_bbpos;
100    Hand.nand_bbpage=hand_p->nand_bbpage;
101// memcpy( &Hand.fw_args, (unsigned char *)(start_addr + 0x8), 32 );
102
103// serial_putc(Hand.nand_eccpos + 48);
104// serial_putc(Hand.nand_bbpos + 48);
105// serial_putc(Hand.nand_bbpage + 48);
106    /* dprintf("\n Hand : bw %d rc %d ps %d ppb %d erase %d pn %d os %d", */
107    /* Hand.nand_bw,Hand.nand_rc,Hand.nand_ps,Hand.nand_ppb,Hand.nand_force_erase,Hand.nand_pn,Hand.nand_os); */
108    serial_put_hex(Hand.fw_args.cpu_id);
109    serial_put_hex(Hand.fw_args.ext_clk);
110#endif
111}
112
113int GET_CUP_INFO_Handle()
114{
115    char temp1[8]="Boot4740",temp2[8]="Boot4750";
116    dprintf("\n GET_CPU_INFO!");
117    if ( Hand.fw_args.cpu_id == 0x4740 )
118        HW_SendPKT(0,temp1,8);
119    else
120        HW_SendPKT(0,temp2,8);
121    udc_state = IDLE;
122    return ERR_OK;
123}
124
125int SET_DATA_ADDERSS_Handle(u8 *buf)
126{
127    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
128    start_addr=(((u32)dreq->wValue)<<16)+(u32)dreq->wIndex;
129    dprintf("\n SET ADDRESS:");
130    serial_put_hex(start_addr);
131    return ERR_OK;
132}
133
134int SET_DATA_LENGTH_Handle(u8 *buf)
135{
136    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
137    ops_length=(((u32)dreq->wValue)<<16)+(u32)dreq->wIndex;
138    dprintf("\n DATA_LENGTH :");
139    serial_put_hex(ops_length);
140    return ERR_OK;
141}
142
143int FLUSH_CACHES_Handle()
144{
145    return ERR_OK;
146}
147
148int PROGRAM_START1_Handle(u8 *buf)
149{
150    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
151    ram_addr=(((u32)dreq->wValue)<<16)+(u32)dreq->wIndex;
152    //dprintf("\n RAM ADDRESS :%x", ram_addr);
153    return ERR_OK;
154}
155
156int PROGRAM_START2_Handle(u8 *buf)
157{
158    void (*f)(void);
159    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
160    f=(void *) ((((u32)dreq->wValue)<<16)+(u32)dreq->wIndex);
161    __dcache_writeback_all();
162    //stop udc connet before execute program!
163    jz_writeb(USB_REG_POWER,0x0); //High speed
164    //dprintf("\n Execute program at %x",(u32)f);
165    f();
166    return ERR_OK;
167}
168
169int MEM_OPS_Handle(u8 *buf)
170{
171    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
172    u32 val;
173
174    switch (dreq->wValue) {
175    case MEM_WRITE8:
176        *((volatile u8*)(start_addr)) = (u8)ops_length;
177        handshake_PKT[0] = ops_length & 0xff;
178        handshake_PKT[1] = 8;
179        break;
180    case MEM_WRITE16:
181        *((volatile u16*)(start_addr)) = (u16)ops_length;
182        handshake_PKT[0] = ops_length & 0xffff;
183        handshake_PKT[1] = 16;
184        break;
185    case MEM_WRITE32:
186        *((volatile u32*)(start_addr)) = ops_length;
187        handshake_PKT[0] = ops_length;
188        handshake_PKT[1] = ops_length >> 16;
189        break;
190    case MEM_READ8:
191        val = *((volatile u8*)(start_addr));
192        handshake_PKT[0] = (u16)val;
193        handshake_PKT[1] = (u16)(val >> 16);
194        break;
195    case MEM_READ16:
196        val = *((volatile u16*)(start_addr));
197        handshake_PKT[0] = (u16)val;
198        handshake_PKT[1] = (u16)(val >> 16);
199        break;
200    case MEM_READ32:
201        val = *((volatile u32*)(start_addr));
202        handshake_PKT[0] = (u16)val;
203        handshake_PKT[1] = (u16)(val >> 16);
204        break;
205    default:
206        handshake_PKT[0] = 0xDEAD;
207        handshake_PKT[1] = 0xC0DE;
208        break;
209    }
210    handshake_PKT[2] = 0;
211    handshake_PKT[3] = 0;
212    HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
213    return ERR_OK;
214}
215
216int NOR_OPS_Handle(u8 *buf)
217{
218    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
219    udc_state = IDLE;
220    return ERR_OK;
221}
222
223int NAND_OPS_Handle(u8 *buf)
224{
225    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
226    u32 temp;
227    int option;
228    u8 CSn;
229
230    CSn = (dreq->wValue>>4) & 0xff;
231    option = (dreq->wValue>>12) & 0xff;
232    nand_enable(CSn);
233    switch ((dreq->wValue)&0xf)
234    {
235    case NAND_QUERY:
236        dprintf("\n Request : NAND_QUERY!");
237        nand_query((u8 *)Bulk_buf);
238        HW_SendPKT(1, Bulk_buf, 8);
239        handshake_PKT[3]=(u16)ERR_OK;
240        udc_state = BULK_IN;
241        break;
242    case NAND_INIT:
243        dprintf("\n Request : NAND_INIT!");
244
245        break;
246    case NAND_MARK_BAD:
247        dprintf("\n Request : NAND_MARK_BAD!");
248        ret_dat = nand_mark_bad(start_addr);
249        handshake_PKT[0] = (u16) ret_dat;
250        handshake_PKT[1] = (u16) (ret_dat>>16);
251        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
252        udc_state = IDLE;
253
254        break;
255    case NAND_READ_OOB:
256        dprintf("\n Request : NAND_READ_OOB!");
257        memset(Bulk_buf,0,ops_length*Hand.nand_ps);
258        ret_dat = nand_read_oob(Bulk_buf,start_addr,ops_length);
259        handshake_PKT[0] = (u16) ret_dat;
260        handshake_PKT[1] = (u16) (ret_dat>>16);
261        HW_SendPKT(1,(u8 *)Bulk_buf,ops_length*Hand.nand_ps);
262        udc_state = BULK_IN;
263        break;
264    case NAND_READ_RAW:
265        dprintf("\n Request : NAND_READ_RAW!");
266        switch (option)
267        {
268        case OOB_ECC:
269            nand_read_raw(Bulk_buf,start_addr,ops_length,option);
270            HW_SendPKT(1,(u8 *)Bulk_buf,ops_length*(Hand.nand_ps + Hand.nand_os));
271            handshake_PKT[0] = (u16) ret_dat;
272            handshake_PKT[1] = (u16) (ret_dat>>16);
273            udc_state = BULK_IN;
274            break;
275        default:
276            nand_read_raw(Bulk_buf,start_addr,ops_length,option);
277            HW_SendPKT(1,(u8 *)Bulk_buf,ops_length*Hand.nand_ps);
278            handshake_PKT[0] = (u16) ret_dat;
279            handshake_PKT[1] = (u16) (ret_dat>>16);
280            udc_state = BULK_IN;
281            break;
282        }
283        break;
284    case NAND_ERASE:
285        dprintf("\n Request : NAND_ERASE!");
286        ret_dat = nand_erase(ops_length,start_addr,
287               Hand.nand_force_erase);
288        handshake_PKT[0] = (u16) ret_dat;
289        handshake_PKT[1] = (u16) (ret_dat>>16);
290        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
291        udc_state = IDLE;
292        dprintf("\n Request : NAND_ERASE_FINISH!");
293        break;
294    case NAND_READ:
295        dprintf("\n Request : NAND_READ!");
296// dprintf("\n Option : %x",option);
297        switch (option)
298        {
299        case OOB_ECC:
300            ret_dat = nand_read(Bulk_buf,start_addr,ops_length,OOB_ECC);
301            handshake_PKT[0] = (u16) ret_dat;
302            handshake_PKT[1] = (u16) (ret_dat>>16);
303            HW_SendPKT(1,(u8 *)Bulk_buf,ops_length*(Hand.nand_ps + Hand.nand_os ));
304            udc_state = BULK_IN;
305            break;
306        case OOB_NO_ECC:
307            ret_dat = nand_read(Bulk_buf,start_addr,ops_length,OOB_NO_ECC);
308            handshake_PKT[0] = (u16) ret_dat;
309            handshake_PKT[1] = (u16) (ret_dat>>16);
310            HW_SendPKT(1,(u8 *)Bulk_buf,ops_length*(Hand.nand_ps + Hand.nand_os));
311            udc_state = BULK_IN;
312            break;
313        case NO_OOB:
314            ret_dat = nand_read(Bulk_buf,start_addr,ops_length,NO_OOB);
315            handshake_PKT[0] = (u16) ret_dat;
316            handshake_PKT[1] = (u16) (ret_dat>>16);
317            HW_SendPKT(1,(u8 *)Bulk_buf,ops_length*Hand.nand_ps);
318            udc_state = BULK_IN;
319            break;
320        }
321        dprintf("\n Request : NAND_READ_FUNISH!");
322        break;
323    case NAND_PROGRAM:
324        dprintf("\n Request : NAND_PROGRAM!");
325// dprintf("\n Option : %x",option);
326        ret_dat = nand_program((void *)Bulk_buf,
327                 start_addr,ops_length,option);
328        dprintf("\n NAND_PROGRAM finish!");
329        handshake_PKT[0] = (u16) ret_dat;
330        handshake_PKT[1] = (u16) (ret_dat>>16);
331        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
332        udc_state = IDLE;
333        break;
334    case NAND_READ_TO_RAM:
335        dprintf("\n Request : NAND_READNAND!");
336        nand_read((u8 *)ram_addr,start_addr,ops_length,NO_OOB);
337        __dcache_writeback_all();
338        handshake_PKT[3]=(u16)ERR_OK;
339        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
340        udc_state = IDLE;
341        break;
342    default:
343        nand_disable(CSn);
344        return ERR_OPS_NOTSUPPORT;
345    }
346
347    return ERR_OK;
348}
349
350int SDRAM_OPS_Handle(u8 *buf)
351{
352    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
353    u32 temp,i;
354    u8 *obj;
355
356    switch ((dreq->wValue)&0xf)
357    {
358    case SDRAM_LOAD:
359// dprintf("\n Request : SDRAM_LOAD!");
360        ret_dat = (u32)memcpy((u8 *)start_addr,Bulk_buf,ops_length);
361        handshake_PKT[0] = (u16) ret_dat;
362        handshake_PKT[1] = (u16) (ret_dat>>16);
363        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
364        udc_state = IDLE;
365        break;
366    }
367    return ERR_OK;
368}
369
370void Borad_Init()
371{
372    dprintf("\n Borad_init! ");
373    serial_put_hex(Hand.fw_args.cpu_id);
374    switch (Hand.fw_args.cpu_id)
375    {
376    case 0x4740:
377        //Init nand flash
378        nand_init_4740(Hand.nand_bw,Hand.nand_rc,Hand.nand_ps,Hand.nand_ppb,
379               Hand.nand_bbpage,Hand.nand_bbpos,Hand.nand_force_erase,Hand.nand_eccpos);
380
381        dprintf("\nnand_ps, nand_ppb, nand_bbpage, nand_bbpos, nand_eccpos\n");
382        serial_put_hex(Hand.nand_ps);
383        serial_put_hex(Hand.nand_ppb);
384        serial_put_hex(Hand.nand_bbpage);
385        serial_put_hex(Hand.nand_bbpos);
386        serial_put_hex(Hand.nand_eccpos);
387
388        nand_program = nand_program_4740;
389        nand_erase = nand_erase_4740;
390        nand_read = nand_read_4740;
391        nand_read_oob = nand_read_oob_4740;
392        nand_read_raw = nand_read_raw_4740;
393        nand_query = nand_query_4740;
394        nand_enable = nand_enable_4740;
395        nand_disable = nand_disable_4740;
396        nand_mark_bad = nand_mark_bad_4740;
397    break;
398    case 0x4750:
399        //Init nand flash
400        nand_init_4750(Hand.nand_bw, Hand.nand_rc, Hand.nand_ps,
401                   Hand.nand_ppb, Hand.nand_bchbit, Hand.nand_eccpos,
402                   Hand.nand_bbpos, Hand.nand_bbpage, Hand.nand_force_erase);
403
404        nand_program = nand_program_4750;
405        nand_erase = nand_erase_4750;
406        nand_read = nand_read_4750;
407        nand_read_oob = nand_read_oob_4750;
408        nand_read_raw = nand_read_raw_4750;
409        nand_query = nand_query_4750;
410        nand_enable = nand_enable_4750;
411        nand_disable = nand_disable_4750;
412        nand_mark_bad = nand_mark_bad_4750;
413    break;
414    default:
415        serial_puts("Not support CPU ID!");
416    }
417}
418
419int CONFIGRATION_Handle(u8 *buf)
420{
421    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
422    switch ((dreq->wValue)&0xf)
423    {
424    case DS_flash_info:
425        dprintf("\n configration :DS_flash_info_t!");
426        config_flash_info();
427        break;
428
429    case DS_hand:
430        dprintf("\n configration :DS_hand_t!");
431        config_hand();
432        break;
433    default:;
434    }
435    Borad_Init();
436    return ERR_OK;
437}
438
439
440

Archive Download this file



interactive