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@sharism.cc>
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 "target/jz4740.h"
23#include "target/error.h"
24#include "target/usb_boot.h"
25#include "usb_boot_defines.h"
26#include "target/nandflash.h"
27#include "usb/udc.h"
28#include "usb/usb.h"
29
30#define dprintf(x) serial_puts(x)
31
32unsigned int (*nand_query)(u8 *);
33int (*nand_init)(int bus_width, int row_cycle, int page_size, int page_per_block,
34         int,int,int,int);
35int (*nand_fini)(void);
36u32 (*nand_program)(void *context, int spage, int pages,int option);
37u32 (*nand_erase)(int blk_num, int sblk, int force);
38u32 (*nand_read)(void *buf, u32 startpage, u32 pagenum,int option);
39u32 (*nand_read_oob)(void *buf, u32 startpage, u32 pagenum);
40u32 (*nand_read_raw)(void *buf, u32 startpage, u32 pagenum,int);
41u32 (*nand_mark_bad) (int bad);
42void (*nand_enable) (unsigned int csn);
43void (*nand_disable) (unsigned int csn);
44
45struct hand Hand;
46extern u32 Bulk_out_buf[BULK_OUT_BUF_SIZE];
47extern u32 Bulk_in_buf[BULK_IN_BUF_SIZE];
48extern u16 handshake_PKT[4];
49extern udc_state;
50extern void *memset(void *s, int c, size_t count);
51extern void *memcpy(void *dest, const void *src, size_t count);
52
53u32 ret_dat;
54u32 start_addr; //program operation start address or sector
55u32 ops_length; //number of operation unit ,in byte or sector
56u32 ram_addr;
57
58void dump_data(unsigned int *p, int size)
59{
60    int i;
61    for(i = 0; i < size; i ++)
62        serial_put_hex(*p++);
63}
64
65void config_flash_info()
66{
67}
68
69void config_hand()
70{
71    memcpy(&Hand, (unsigned char *)Bulk_out_buf, sizeof(struct hand));
72}
73
74int GET_CUP_INFO_Handle()
75{
76    dprintf("\n GET_CPU_INFO:\t");
77    serial_put_hex(Hand.fw_args.cpu_id);
78    switch (Hand.fw_args.cpu_id) {
79    case 0x4760:
80        HW_SendPKT(0, "Boot4760", 8);
81        break;
82    case 0x4740:
83        HW_SendPKT(0, "Boot4740", 8);
84        break;
85    default:
86        HW_SendPKT(0, " UNKNOW ", 8);
87        break;
88    }
89    udc_state = IDLE;
90    return ERR_OK;
91}
92           
93int SET_DATA_ADDERSS_Handle(u8 *buf)
94{
95    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
96    start_addr=(((u32)dreq->wValue)<<16)+(u32)dreq->wIndex;
97    dprintf("\n SET ADDRESS:\t");
98    serial_put_hex(start_addr);
99    return ERR_OK;
100}
101        
102int SET_DATA_LENGTH_Handle(u8 *buf)
103{
104    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
105    ops_length=(((u32)dreq->wValue)<<16)+(u32)dreq->wIndex;
106    dprintf("\n DATA_LENGTH:\t");
107    serial_put_hex(ops_length);
108    return ERR_OK;
109}
110
111int FLUSH_CACHES_Handle()
112{
113    return ERR_OK;
114}
115    
116int PROGRAM_START1_Handle(u8 *buf)
117{
118    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
119    ram_addr=(((u32)dreq->wValue)<<16)+(u32)dreq->wIndex;
120    //dprintf("\n RAM ADDRESS :%x", ram_addr);
121    return ERR_OK;
122}
123
124int PROGRAM_START2_Handle(u8 *buf)
125{
126    void (*f)(void);
127    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
128    f=(void *) ((((u32)dreq->wValue)<<16)+(u32)dreq->wIndex);
129    __dcache_writeback_all();
130    //stop udc connet before execute program!
131    jz_writeb(USB_REG_POWER,0x0); //High speed
132    //dprintf("\n Execute program at %x",(u32)f);
133    f();
134    return ERR_OK;
135}
136          
137int NOR_OPS_Handle(u8 *buf)
138{
139    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
140    return ERR_OK;
141}
142
143int NAND_OPS_Handle(u8 *buf)
144{
145    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
146    u32 temp;
147    int option;
148    u8 CSn;
149
150    CSn = (dreq->wValue>>4) & 0xff;
151    option = (dreq->wValue>>12) & 0xff;
152    nand_enable(CSn);
153    switch ((dreq->wValue)&0xf)
154    {
155    case NAND_QUERY:
156        dprintf("\n Request : NAND_QUERY!");
157        nand_query((u8 *)Bulk_in_buf);
158        HW_SendPKT(1, Bulk_in_buf, 8);
159        handshake_PKT[3]=(u16)ERR_OK;
160        udc_state = BULK_IN;
161        break;
162    case NAND_INIT:
163        dprintf("\n Request : NAND_INIT!");
164
165        break;
166    case NAND_MARK_BAD:
167        dprintf("\n Request : NAND_MARK_BAD!");
168        ret_dat = nand_mark_bad(start_addr);
169        handshake_PKT[0] = (u16) ret_dat;
170        handshake_PKT[1] = (u16) (ret_dat>>16);
171        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
172        udc_state = IDLE;
173
174        break;
175    case NAND_READ_OOB:
176        dprintf("\n Request : NAND_READ_OOB!");
177        memset(Bulk_in_buf,0,ops_length*Hand.nand_ps);
178        ret_dat = nand_read_oob(Bulk_in_buf,start_addr,ops_length);
179        handshake_PKT[0] = (u16) ret_dat;
180        handshake_PKT[1] = (u16) (ret_dat>>16);
181        HW_SendPKT(1,(u8 *)Bulk_in_buf,ops_length*Hand.nand_ps);
182        udc_state = BULK_IN;
183        break;
184    case NAND_READ_RAW:
185        dprintf("\n Request : NAND_READ_RAW!");
186        switch (option)
187        {
188        case OOB_ECC:
189            nand_read_raw(Bulk_in_buf,start_addr,ops_length,option);
190            HW_SendPKT(1,(u8 *)Bulk_in_buf,ops_length*(Hand.nand_ps + Hand.nand_os));
191            handshake_PKT[0] = (u16) ret_dat;
192            handshake_PKT[1] = (u16) (ret_dat>>16);
193            udc_state = BULK_IN;
194            break;
195        default:
196            nand_read_raw(Bulk_in_buf,start_addr,ops_length,option);
197            HW_SendPKT(1,(u8 *)Bulk_in_buf,ops_length*Hand.nand_ps);
198            handshake_PKT[0] = (u16) ret_dat;
199            handshake_PKT[1] = (u16) (ret_dat>>16);
200            udc_state = BULK_IN;
201            break;
202        }
203        break;
204    case NAND_ERASE:
205        dprintf("\n Request : NAND_ERASE");
206        ret_dat = nand_erase(ops_length,start_addr,
207               Hand.nand_force_erase);
208        handshake_PKT[0] = (u16) ret_dat;
209        handshake_PKT[1] = (u16) (ret_dat>>16);
210        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
211        udc_state = IDLE;
212        dprintf(" ... finished.");
213        break;
214    case NAND_READ:
215        dprintf("\n Request : NAND_READ!");
216        switch (option) {
217        case OOB_ECC:
218            ret_dat = nand_read(Bulk_in_buf,start_addr,ops_length,OOB_ECC);
219            handshake_PKT[0] = (u16) ret_dat;
220            handshake_PKT[1] = (u16) (ret_dat>>16);
221            HW_SendPKT(1,(u8 *)Bulk_in_buf,ops_length*(Hand.nand_ps + Hand.nand_os ));
222            udc_state = BULK_IN;
223            break;
224        case OOB_NO_ECC:
225            ret_dat = nand_read(Bulk_in_buf,start_addr,ops_length,OOB_NO_ECC);
226            handshake_PKT[0] = (u16) ret_dat;
227            handshake_PKT[1] = (u16) (ret_dat>>16);
228            HW_SendPKT(1,(u8 *)Bulk_in_buf,ops_length*(Hand.nand_ps + Hand.nand_os));
229            udc_state = BULK_IN;
230            break;
231        case NO_OOB:
232            ret_dat = nand_read(Bulk_in_buf,start_addr,ops_length,NO_OOB);
233            handshake_PKT[0] = (u16) ret_dat;
234            handshake_PKT[1] = (u16) (ret_dat>>16);
235            HW_SendPKT(1,(u8 *)Bulk_in_buf,ops_length*Hand.nand_ps);
236            udc_state = BULK_IN;
237            break;
238        }
239        dprintf(" ... finished.");
240        break;
241    case NAND_PROGRAM:
242        dprintf("\n Request : NAND_PROGRAM!");
243        ret_dat = nand_program((void *)Bulk_out_buf,
244                 start_addr,ops_length,option);
245        handshake_PKT[0] = (u16) ret_dat;
246        handshake_PKT[1] = (u16) (ret_dat>>16);
247        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
248        udc_state = IDLE;
249        dprintf(" ... finished.");
250        break;
251    case NAND_READ_TO_RAM:
252        dprintf("\n Request : NAND_READ_TO_RAM!");
253        nand_read((u8 *)ram_addr,start_addr,ops_length,NO_OOB);
254        __dcache_writeback_all();
255        handshake_PKT[3]=(u16)ERR_OK;
256        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
257        udc_state = IDLE;
258        break;
259    default:
260        nand_disable(CSn);
261        return ERR_OPS_NOTSUPPORT;
262    }
263
264    return ERR_OK;
265}
266
267int SDRAM_OPS_Handle(u8 *buf)
268{
269    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
270    u32 temp,i;
271    u8 *obj;
272
273    switch ((dreq->wValue)&0xf)
274    {
275    case SDRAM_LOAD:
276        //dprintf("\n Request : SDRAM_LOAD!");
277        ret_dat = (u32)memcpy((u8 *)start_addr,Bulk_out_buf,ops_length);
278        handshake_PKT[0] = (u16) ret_dat;
279        handshake_PKT[1] = (u16) (ret_dat>>16);
280        HW_SendPKT(1,handshake_PKT,sizeof(handshake_PKT));
281        udc_state = IDLE;
282        break;
283    }
284    return ERR_OK;
285}
286
287void Borad_Init()
288{
289    dprintf("\n Borad_init! ");
290    serial_put_hex(Hand.fw_args.cpu_id);
291    switch (Hand.fw_args.cpu_id)
292    {
293    case 0x4740:
294        //Init nand flash
295        nand_init_4740(Hand.nand_bw, Hand.nand_rc, Hand.nand_ps,
296                   Hand.nand_ppb, Hand.nand_bbpage, Hand.nand_bbpos,
297                   Hand.nand_force_erase, Hand.nand_eccpos);
298    
299        nand_program = nand_program_4740;
300        nand_erase = nand_erase_4740;
301        nand_read = nand_read_4740;
302        nand_read_oob = nand_read_oob_4740;
303        nand_read_raw = nand_read_raw_4740;
304        nand_query = nand_query_4740;
305        nand_enable = nand_enable_4740;
306        nand_disable = nand_disable_4740;
307        nand_mark_bad = nand_mark_bad_4740;
308        break;
309    case 0x4760:
310        //Init nand flash
311        nand_init_4760(Hand.nand_bw, Hand.nand_rc, Hand.nand_ps,
312                   Hand.nand_ppb, Hand.nand_bchbit, Hand.nand_eccpos,
313                   Hand.nand_bbpos, Hand.nand_bbpage, Hand.nand_force_erase);
314
315        nand_program=nand_program_4760;
316        nand_erase =nand_erase_4760;
317        nand_read =nand_read_4760;
318        nand_read_oob=nand_read_oob_4760;
319        nand_read_raw=nand_read_raw_4760;
320        nand_query = nand_query_4760;
321        nand_enable = nand_enable_4760;
322        nand_disable= nand_disable_4760;
323        nand_mark_bad = nand_mark_bad_4760;
324        break;
325    default:
326        serial_puts("\n Not support CPU ID!");
327    }
328}
329
330int CONFIGRATION_Handle(u8 *buf)
331{
332    dprintf("\n Configuration:\t");
333
334    USB_DeviceRequest *dreq = (USB_DeviceRequest *)buf;
335    switch ((dreq->wValue)&0xf) {
336    case DS_flash_info:
337        dprintf("DS_flash_info_t!");
338        config_flash_info();
339        break;
340
341    case DS_hand:
342        dprintf("DS_hand_t!");
343        config_hand();
344        break;
345    default:
346        ;
347    }
348
349    Borad_Init();
350    return ERR_OK;
351}
352
353
354

Archive Download this file



interactive