NOR/SPEARSMI: fix segfault
[openocd.git] / src / flash / nor / spearsmi.c
index 19a4405498b4049d14be40b030eda5fd28e7d967..5e6a2c472ad2e8d9684a8f4b69e142548cfde7c3 100644 (file)
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+/* SPEAr Serial Memory Interface (SMI) controller is a SPI bus controller
+ * specifically designed for SPI memories.
+ * Only SPI "mode 3" (CPOL=1 and CPHA=1) is supported.
+ * Two working modes are available:
+ * - SW mode: the SPI is controlled by SW. Any custom commands can be sent
+ *   on the bus.
+ * - HW mode: the SPI but is under SMI control. Memory content is directly
+ *   accessible in CPU memory space. CPU can read, write and execute memory
+ *   content. */
+
 /* ATTENTION:
  * To have flash memory mapped in CPU memory space, the SMI controller
  * have to be in "HW mode". This requires following constraints:
@@ -29,7 +39,6 @@
 #endif
 
 #include "imp.h"
-#include "spearsmi.h"
 #include <jtag/jtag.h>
 #include <helper/time_support.h>
 
 #define SMI_PROBE_TIMEOUT (100)
 #define SMI_MAX_TIMEOUT  (3000)
 
+struct spearsmi_flash_bank
+{
+       int probed;
+       uint32_t io_base;
+       uint32_t bank_num;
+       struct flash_device *dev;
+};
+
 /* data structure to maintain flash ids from different vendors */
 struct flash_device {
        char *name;
@@ -136,6 +153,9 @@ struct flash_device {
        .size_in_bytes = size   \
 }
 
+/* List below is taken from Linux driver. It is not exhaustive of all the
+ * possible SPI memories, nor exclusive for SMI. Could be shared with
+ * other SPI drivers. */
 static struct flash_device flash_devices[] = {
        /* name, erase_cmd, device_id, pagesize, sectorsize, size_in_bytes */
        FLASH_ID("st m25p05",      0xd8, 0x00102020, 0x80,  0x8000,  0x10000),
@@ -217,6 +237,9 @@ static int poll_tff(struct target *target, uint32_t io_base, int timeout)
        return ERROR_FLASH_OPERATION_FAILED;
 }
 
+/* Read the status register of the external SPI flash chip.
+ * The operation is triggered by setting SMI_RSR bit.
+ * SMI sends the proper SPI command (0x05) and returns value in SMI_SR */
 static int read_status_reg(struct flash_bank *bank, uint32_t *status)
 {
        struct target *target = bank->target;
@@ -235,7 +258,6 @@ static int read_status_reg(struct flash_bank *bank, uint32_t *status)
        /* clear transmit finished flag */
        SMI_CLEAR_TFF();
 
-       /* Check write enabled */
        *status = SMI_READ_REG(SMI_SR) & 0x0000ffff;
 
        /* clean-up SMI_CR2 */
@@ -268,6 +290,9 @@ static int wait_till_ready(struct flash_bank *bank, int timeout)
        return ERROR_FAIL;
 }
 
+/* Send "write enable" command to SPI flash chip.
+ * The operation is triggered by setting SMI_WE bit, and SMI sends
+ * the proper SPI command (0x06) */
 static int smi_write_enable(struct flash_bank *bank)
 {
        struct target *target = bank->target;
@@ -337,7 +362,7 @@ static int smi_erase_sector(struct flash_bank *bank, int sector)
        /* clear transmit finished flag */
        SMI_CLEAR_TFF();
 
-       /* send erase command */
+       /* send SPI command "block erase" */
        cmd = erase_command(spearsmi_info, bank->sectors[sector].offset);
        SMI_WRITE_REG(SMI_TR, cmd);
        SMI_WRITE_REG(SMI_CR2, spearsmi_info->bank_num | SMI_SEND | SMI_TX_LEN_4);
@@ -554,7 +579,7 @@ static int read_flash_id(struct flash_bank *bank, uint32_t *id)
        /* clear transmit finished flag */
        SMI_CLEAR_TFF();
 
-       /* Require read flash ID */
+       /* Send SPI command "read ID" */
        SMI_WRITE_REG(SMI_TR, SMI_READ_ID);
        SMI_WRITE_REG(SMI_CR2,
                spearsmi_info->bank_num | SMI_SEND | SMI_RX_LEN_3 | SMI_TX_LEN_1);
@@ -565,7 +590,7 @@ static int read_flash_id(struct flash_bank *bank, uint32_t *id)
        /* clear transmit finished flag */
        SMI_CLEAR_TFF();
 
-       /* read ID */
+       /* read ID from Receive Register */
        *id = SMI_READ_REG(SMI_RR) & 0x00ffffff;
        return ERROR_OK;
 }
@@ -622,6 +647,7 @@ static int spearsmi_probe(struct flash_bank *bank)
        if (retval != ERROR_OK)
                return retval;
 
+       spearsmi_info->dev = NULL;
        for (struct flash_device *p = flash_devices; p->name ; p++)
                if (p->device_id == id) {
                        spearsmi_info->dev = p;

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)