gdb_server: correctly report flash sector sizes
authorDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 20 Jan 2010 18:43:32 +0000 (10:43 -0800)
committerDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 20 Jan 2010 18:43:32 +0000 (10:43 -0800)
Report each region of same-size sectors separately, instead of
incorrectly reporting that every sector has the same size.

This is a longstanding bug on NOR flash chips with non-uniform
sector sizes.  It was largely hidden by other bugs in flash
handling.  When some of those were recently fixed, this one was
exposed as a regression on str710.

[oyvind.harboe@zylin.com: update the loop to behave on str7 ]

Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
src/server/gdb_server.c

index 6ed7243d28498f1889caca7c4d72936b4628367c..f3e0575904b00fb464781aed65cfa6b2b15deb51 100644 (file)
@@ -1613,22 +1613,6 @@ static int decode_xfer_read(char *buf, char **annex, int *ofs, unsigned int *len
        return 0;
 }
 
-static int gdb_calc_blocksize(struct flash_bank *bank)
-{
-       uint32_t i;
-       uint32_t block_size = 0xffffffff;
-
-       /* loop through all sectors and return smallest sector size */
-
-       for (i = 0; i < (uint32_t)bank->num_sectors; i++)
-       {
-               if (bank->sectors[i].size < block_size)
-                       block_size = bank->sectors[i].size;
-       }
-
-       return block_size;
-}
-
 static int compare_bank (const void * a, const void * b)
 {
        struct flash_bank *b1, *b2;
@@ -1666,7 +1650,6 @@ static int gdb_memory_map(struct connection *connection,
        int offset;
        int length;
        char *separator;
-       int blocksize;
        uint32_t ram_start = 0;
        int i;
 
@@ -1683,6 +1666,7 @@ static int gdb_memory_map(struct connection *connection,
         * it has no concept of non-cacheable read/write memory (i/o etc).
         *
         * FIXME Most non-flash addresses are *NOT* RAM!  Don't lie.
+        * Current versions of GDB assume unlisted addresses are RAM...
         */
        banks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count());
 
@@ -1701,29 +1685,60 @@ static int gdb_memory_map(struct connection *connection,
                        compare_bank);
 
        for (i = 0; i < flash_get_bank_count(); i++) {
+               int j;
+               unsigned sector_size = 0;
+               uint32_t start, end;
+
                p = banks[i];
+               start = p->base;
+               end = p->base + p->size;
 
                if (ram_start < p->base)
                        xml_printf(&retval, &xml, &pos, &size,
                                "<memory type=\"ram\" start=\"0x%x\" "
                                        "length=\"0x%x\"/>\n",
-                               ram_start, p->base-ram_start);
+                               ram_start, p->base - ram_start);
 
-               /* If device has uneven sector sizes, eg. str7, lpc
-                * we pass the smallest sector size to gdb memory map
-                *
-                * FIXME Don't lie about flash regions with different
-                * sector sizes; just tell GDB about each region as
-                * if it were a separate flash device.
+               /* Report adjacent groups of same-size sectors.  So for
+                * example top boot CFI flash will list an initial region
+                * with several large sectors (maybe 128KB) and several
+                * smaller ones at the end (maybe 32KB).  STR7 will have
+                * regions with 8KB, 32KB, and 64KB sectors; etc.
                 */
-               blocksize = gdb_calc_blocksize(p);
+               for (j = 0; j < p->num_sectors; j++) {
+                       unsigned group_len;
+
+                       /* Maybe start a new group of sectors. */
+                       if (sector_size == 0) {
+                               start = p->base + p->sectors[j].offset;
+                               xml_printf(&retval, &xml, &pos, &size,
+                                       "<memory type=\"flash\" "
+                                               "start=\"0x%x\" ",
+                                       start);
+                               sector_size = p->sectors[j].size;
+                       }
+
+                       /* Does this finish a group of sectors?
+                        * If not, continue an already-started group.
+                        */
+                       if (j == p->num_sectors -1)
+                               group_len = (p->base + p->size) - start;
+                       else if (p->sectors[j + 1].size != sector_size)
+                               group_len = p->base + p->sectors[j + 1].offset
+                                               - start;
+                       else
+                               continue;
+
+                       xml_printf(&retval, &xml, &pos, &size,
+                               "length=\"0x%x\">\n"
+                               "<property name=\"blocksize\">"
+                                       "0x%x</property>\n"
+                               "</memory>\n",
+                               group_len,
+                               sector_size);
+                       sector_size = 0;
+               }
 
-               xml_printf(&retval, &xml, &pos, &size,
-                       "<memory type=\"flash\" start=\"0x%x\" "
-                               "length=\"0x%x\">\n" \
-                       "<property name=\"blocksize\">0x%x</property>\n" \
-                       "</memory>\n", \
-                       p->base, p->size, blocksize);
                ram_start = p->base + p->size;
        }
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)