]> git.sur5r.net Git - openocd/commitdiff
Rolf Meeser <rolfm_9dq@yahoo.de>
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 9 Sep 2009 16:11:33 +0000 (16:11 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Wed, 9 Sep 2009 16:11:33 +0000 (16:11 +0000)
This patch adds target algorithm support for those flash devices that do not support DQ5 polling. So far they could only be programmed with host algorithm, but this was way too slow.

git-svn-id: svn://svn.berlios.de/openocd/trunk@2682 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/flash/cfi.c
src/flash/non_cfi.c

index 46e5528d725b16d8fb92e1cb8b9ad1e73f6c34f4..66b94c966fcfb826dc7f5314e91135e0b499fe5f 100644 (file)
@@ -1384,6 +1384,31 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
                0xeafffffe      /* b    81ac <sp_16_done>              */
                };
 
+               static const uint32_t word_16_code_dq7only[] = {
+                               /* <sp_16_code>:                       */
+               0xe0d050b2,     /* ldrh r5, [r0], #2                   */
+               0xe1c890b0,     /* strh r9, [r8]                       */
+               0xe1cab0b0,     /* strh r11, [r10]                              */
+               0xe1c830b0,     /* strh r3, [r8]                                */
+               0xe1c150b0,     /* strh r5, [r1]                       */
+               0xe1a00000,     /* nop                  (mov r0,r0)    */
+                               /*                                     */
+                               /* <sp_16_busy>:                       */
+               0xe1d160b0,     /* ldrh r6, [r1]                       */
+               0xe0257006,     /* eor  r7, r5, r6                     */
+               0xe2177080,     /* ands r7, #0x80                      */
+               0x1afffffb,     /* bne  8168 <sp_16_busy>              */
+                               /*                                     */
+               0xe2522001,     /* subs r2, r2, #1      ; 0x1          */
+               0x03a05080,     /* moveq        r5, #128        ; 0x80 */
+               0x0a000001,     /* beq  81ac <sp_16_done>              */
+               0xe2811002,     /* add  r1, r1, #2      ; 0x2          */
+               0xeafffff0,     /* b    8158 <sp_16_code>              */
+                               /*                                     */
+                               /* 000081ac <sp_16_done>:              */
+               0xeafffffe      /* b    81ac <sp_16_done>              */
+               };
+
                static const uint32_t word_8_code[] = {
                                /* 000081b0 <sp_16_code_end>:          */
                0xe4d05001,     /* ldrb r5, [r0], #1                   */
@@ -1423,10 +1448,10 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
        armv4_5_info.core_state = ARMV4_5_STATE_ARM;
 
        /* flash write code */
+       int target_code_size;
        if (!cfi_info->write_algorithm)
        {
                uint8_t *target_code;
-               int target_code_size;
                const uint32_t *src;
 
                /* convert bus-width dependent algorithm code to correct endiannes */
@@ -1437,8 +1462,18 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
                        target_code_size = sizeof(word_8_code);
                        break;
                case 2:
-                       src = word_16_code;
-                       target_code_size = sizeof(word_16_code);
+                       /* Check for DQ5 support */
+                       if( cfi_info->status_poll_mask & (1 << 5) )
+                       {
+                               src = word_16_code;
+                               target_code_size = sizeof(word_16_code);
+                       }
+                       else
+                       {
+                               /* No DQ5 support. Use DQ7 DATA# polling only. */
+                               src = word_16_code_dq7only;
+                               target_code_size = sizeof(word_16_code_dq7only);
+                       }
                        break;
                case 4:
                        src = word_32_code;
@@ -1515,7 +1550,7 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
 
                retval = target_run_algorithm(target, 0, NULL, 10, reg_params,
                                                     cfi_info->write_algorithm->address,
-                                                    cfi_info->write_algorithm->address + ((24 * 4) - 4),
+                                                    cfi_info->write_algorithm->address + ((target_code_size) - 4),
                                                     10000, &armv4_5_info);
 
                status = buf_get_u32(reg_params[5].value, 0, 32);
@@ -1532,7 +1567,7 @@ static int cfi_spansion_write_block(struct flash_bank_s *bank, uint8_t *buffer,
                count -= thisrun_count;
        }
 
-       target_free_working_area(target, source);
+       target_free_all_working_areas(target);
 
        destroy_reg_param(&reg_params[0]);
        destroy_reg_param(&reg_params[1]);
index 90de787945a6d4170bfb26ad9439b6c9b006999c..34acd2a40ccf74fcfe21a483ffd11b9319030729 100644 (file)
@@ -140,7 +140,10 @@ static non_cfi_t non_cfi_flashes[] = {
 
        /* SST 39VF* do not support DQ5 status polling - this currently is
           only supported by the host algorithm, not by the target code using
-          the work area. */
+          the work area.
+           Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
+           without DQ5 status polling are supported by the target code.
+        */
        {
                .mfr = CFI_MFR_SST,
                .id = 0x2782,                           /* SST39xF160 */