This is an automated email from Gerrit.

Tarek BOCHKATI (tarek.bouchk...@gmail.com) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/6050

-- gerrit

commit acafce3c7c59fe486e30c2f20f9773ca53854ca5
Author: Tarek BOCHKATI <tarek.bouchk...@st.com>
Date:   Thu Feb 4 22:43:52 2021 +0100

    stm32l4x: add support of STM32WL5x dual core
    
    Change-Id: Ifb6e291bf97f814f0b9987b2c40f3037959f7af4
    Signed-off-by: Tarek BOCHKATI <tarek.bouchk...@st.com>

diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c
index 63d2d31..99ff0f6 100644
--- a/src/flash/nor/stm32l4x.c
+++ b/src/flash/nor/stm32l4x.c
@@ -137,6 +137,9 @@ enum stm32l4_flash_reg_index {
        STM32_FLASH_OPTKEYR_INDEX,
        STM32_FLASH_SR_INDEX,
        STM32_FLASH_CR_INDEX,
+       /* for some devices like STM32WL5x, the CPU2 have a dedicated C2CR 
register w/o LOCKs,
+        * so it uses the C2CR for flash operations and CR for checking locks 
and locking */
+       STM32_FLASH_CR_WLK_INDEX, /* FLASH_CR_WITH_LOCK */
        STM32_FLASH_OPTR_INDEX,
        STM32_FLASH_WRP1AR_INDEX,
        STM32_FLASH_WRP1BR_INDEX,
@@ -165,6 +168,20 @@ static const uint32_t 
stm32l4_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
        [STM32_FLASH_WRP2BR_INDEX]   = 0x050,
 };
 
+static const uint32_t stm32wl_cpu2_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
+       [STM32_FLASH_ACR_INDEX]      = 0x000,
+       [STM32_FLASH_KEYR_INDEX]     = 0x008,
+       [STM32_FLASH_OPTKEYR_INDEX]  = 0x010,
+       [STM32_FLASH_SR_INDEX]       = 0x060,
+       [STM32_FLASH_CR_INDEX]       = 0x064,
+       [STM32_FLASH_CR_WLK_INDEX]   = 0x014,
+       [STM32_FLASH_OPTR_INDEX]     = 0x040,
+       [STM32_FLASH_WRP1AR_INDEX]   = 0x058,
+       [STM32_FLASH_WRP1BR_INDEX]   = 0x05C,
+       [STM32_FLASH_WRP2AR_INDEX]   = 0x068,
+       [STM32_FLASH_WRP2BR_INDEX]   = 0x06C,
+};
+
 static const uint32_t stm32l5_ns_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {
        [STM32_FLASH_ACR_INDEX]      = 0x000,
        [STM32_FLASH_KEYR_INDEX]     = 0x008,
@@ -527,7 +544,7 @@ static const struct stm32l4_part_info stm32l4_parts[] = {
          .id                    = 0x497,
          .revs                  = stm32_497_revs,
          .num_revs              = ARRAY_SIZE(stm32_497_revs),
-         .device_str            = "STM32WLEx",
+         .device_str            = "STM32WLEx/WL5x",
          .max_flash_size_kb     = 256,
          .flags                 = F_NONE,
          .flash_regs_base       = 0x58004000,
@@ -731,14 +748,22 @@ static int stm32l4_set_secbb(struct flash_bank *bank, 
uint32_t value)
        return ERROR_OK;
 }
 
+static inline int stm32l4_get_flash_cr_with_lock_index(struct flash_bank *bank)
+{
+       struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;
+       return (stm32l4_info->flash_regs[STM32_FLASH_CR_WLK_INDEX]) ?
+               STM32_FLASH_CR_WLK_INDEX : STM32_FLASH_CR_INDEX;
+}
+
 static int stm32l4_unlock_reg(struct flash_bank *bank)
 {
+       const uint32_t flash_cr_index = 
stm32l4_get_flash_cr_with_lock_index(bank);
        uint32_t ctrl;
 
        /* first check if not already unlocked
         * otherwise writing on STM32_FLASH_KEYR will fail
         */
-       int retval = stm32l4_read_flash_reg_by_index(bank, 
STM32_FLASH_CR_INDEX, &ctrl);
+       int retval = stm32l4_read_flash_reg_by_index(bank, flash_cr_index, 
&ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -754,7 +779,7 @@ static int stm32l4_unlock_reg(struct flash_bank *bank)
        if (retval != ERROR_OK)
                return retval;
 
-       retval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
&ctrl);
+       retval = stm32l4_read_flash_reg_by_index(bank, flash_cr_index, &ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -768,9 +793,10 @@ static int stm32l4_unlock_reg(struct flash_bank *bank)
 
 static int stm32l4_unlock_option_reg(struct flash_bank *bank)
 {
+       const uint32_t flash_cr_index = 
stm32l4_get_flash_cr_with_lock_index(bank);
        uint32_t ctrl;
 
-       int retval = stm32l4_read_flash_reg_by_index(bank, 
STM32_FLASH_CR_INDEX, &ctrl);
+       int retval = stm32l4_read_flash_reg_by_index(bank, flash_cr_index, 
&ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -786,7 +812,7 @@ static int stm32l4_unlock_option_reg(struct flash_bank 
*bank)
        if (retval != ERROR_OK)
                return retval;
 
-       retval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
&ctrl);
+       retval = stm32l4_read_flash_reg_by_index(bank, flash_cr_index, &ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -825,7 +851,8 @@ static int stm32l4_perform_obl_launch(struct flash_bank 
*bank)
        stm32l4_info->probed = false;
 
 err_lock:
-       retval2 = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
FLASH_LOCK | FLASH_OPTLOCK);
+       retval2 = stm32l4_write_flash_reg_by_index(bank, 
stm32l4_get_flash_cr_with_lock_index(bank),
+                       FLASH_LOCK | FLASH_OPTLOCK);
 
        if (retval != ERROR_OK)
                return retval;
@@ -864,7 +891,8 @@ static int stm32l4_write_option(struct flash_bank *bank, 
uint32_t reg_offset,
        retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
 
 err_lock:
-       retval2 = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
FLASH_LOCK | FLASH_OPTLOCK);
+       retval2 = stm32l4_write_flash_reg_by_index(bank, 
stm32l4_get_flash_cr_with_lock_index(bank),
+                       FLASH_LOCK | FLASH_OPTLOCK);
 
        if (retval != ERROR_OK)
                return retval;
@@ -1058,7 +1086,7 @@ static int stm32l4_erase(struct flash_bank *bank, 
unsigned int first,
        }
 
 err_lock:
-       retval2 = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
FLASH_LOCK);
+       retval2 = stm32l4_write_flash_reg_by_index(bank, 
stm32l4_get_flash_cr_with_lock_index(bank), FLASH_LOCK);
 
        if (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {
                /* if failed to restore SECBBxRy to zeros, just return failure 
*/
@@ -1437,7 +1465,7 @@ static int stm32l4_write(struct flash_bank *bank, const 
uint8_t *buffer,
 
 
 err_lock:
-       retval2 = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
FLASH_LOCK);
+       retval2 = stm32l4_write_flash_reg_by_index(bank, 
stm32l4_get_flash_cr_with_lock_index(bank), FLASH_LOCK);
 
        if (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {
                /* if failed to restore SECBBxRy to zeros, just return failure 
*/
@@ -1472,6 +1500,7 @@ static int stm32l4_read_idcode(struct flash_bank *bank, 
uint32_t *id)
 static int stm32l4_probe(struct flash_bank *bank)
 {
        struct target *target = bank->target;
+       struct armv7m_common *armv7m = target_to_armv7m(target);
        struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;
        const struct stm32l4_part_info *part_info;
        uint16_t flash_size_kb = 0xffff;
@@ -1607,7 +1636,6 @@ static int stm32l4_probe(struct flash_bank *bank)
        case 0x466: /* STM32G03/G04xx */
        case 0x468: /* STM32G43/G44xx */
        case 0x479: /* STM32G49/G4Axx */
-       case 0x497: /* STM32WLEx */
                /* single bank flash */
                page_size_kb = 2;
                num_pages = flash_size_kb / page_size_kb;
@@ -1698,6 +1726,14 @@ static int stm32l4_probe(struct flash_bank *bank)
                num_pages = flash_size_kb / page_size_kb;
                stm32l4_info->bank1_sectors = num_pages;
                break;
+       case 0x497: /* STM32WLEx/WL5x */
+               /* single bank flash */
+               page_size_kb = 2;
+               num_pages = flash_size_kb / page_size_kb;
+               stm32l4_info->bank1_sectors = num_pages;
+               if (armv7m->debug_ap->ap_num == 1)
+                       stm32l4_info->flash_regs = stm32wl_cpu2_flash_regs;
+               break;
        default:
                LOG_ERROR("unsupported device");
                return ERROR_FAIL;
@@ -1858,7 +1894,7 @@ static int stm32l4_mass_erase(struct flash_bank *bank)
        retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
 
 err_lock:
-       retval2 = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 
FLASH_LOCK);
+       retval2 = stm32l4_write_flash_reg_by_index(bank, 
stm32l4_get_flash_cr_with_lock_index(bank), FLASH_LOCK);
 
        if (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {
                /* if failed to restore SECBBxRy to zeros, just return failure 
*/
diff --git a/tcl/target/stm32wlx.cfg b/tcl/target/stm32wlx.cfg
index 961850a..94bafb3 100644
--- a/tcl/target/stm32wlx.cfg
+++ b/tcl/target/stm32wlx.cfg
@@ -12,16 +12,49 @@ if { [info exists CHIPNAME] } {
        set _CHIPNAME stm32wlx
 }
 
-set _ENDIAN little
+if { [info exists DUAL_CORE] } {
+       set $_CHIPNAME.DUAL_CORE $DUAL_CORE
+       unset DUAL_CORE
+} else {
+       set $_CHIPNAME.DUAL_CORE 0
+}
+
+if { [info exists WKUP_CM0P] } {
+       set $_CHIPNAME.WKUP_CM0P $WKUP_CM0P
+       unset WKUP_CM0P
+} else {
+       set $_CHIPNAME.WKUP_CM0P 0
+}
+
+# Issue a warning when hla is used, and fallback to single core configuration
+if { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {
+       echo "Warning : hla does not support multicore debugging"
+       set $_CHIPNAME.DUAL_CORE 0
+       set $_CHIPNAME.WKUP_CM0P 0
+}
 
+# setup the Work-area start address and size
 # Work-area is a space in RAM used for flash programming
-# By default use 20kB
+
+# Memory map for known devices:
+# STM32WL   x5JC   x5JB   x5J8
+#   FLASH   256    128    64
+#   SRAM1   32     16     0
+#   SRAM2   32     32     20
+
+# By default use 8kB
 if { [info exists WORKAREASIZE] } {
        set _WORKAREASIZE $WORKAREASIZE
 } else {
-       set _WORKAREASIZE 0x5000
+       set _WORKAREASIZE 0x2000
 }
 
+# Use SRAM2 as work area (some devices do not have SRAM1):
+set WORKAREASTART_CM4   0x20008000
+set WORKAREASTART_CM0P  $WORKAREASTART_CM4 + $_WORKAREASIZE
+
+echo $WORKAREASTART_CM0P
+
 #jtag scan chain
 if { [info exists CPUTAPID] } {
        set _CPUTAPID $CPUTAPID
@@ -41,36 +74,20 @@ if {[using_jtag]} {
        jtag newtap $_CHIPNAME bs -irlen 5
 }
 
-set _TARGETNAME $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap
-
-$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 
$_WORKAREASIZE -work-area-backup 0
-
-flash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME
-flash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME
-
-# Common knowledges tells JTAG speed should be <= F_CPU/6.
-# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on
-# the safe side.
-#
-# Note that there is a pretty wide band where things are
-# more or less stable, see http://openocd.zylin.com/#/c/3366/
-adapter speed 500
+target create $_CHIPNAME.cpu0 cortex_m -endian little -dap $_CHIPNAME.dap
 
-adapter srst delay 100
-if {[using_jtag]} {
-       jtag_ntrst_delay 100
-}
+$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM4 -work-area-size 
$_WORKAREASIZE -work-area-backup 0
 
-reset_config srst_nogate
+flash bank $_CHIPNAME.flash.cpu0 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu0
+flash bank $_CHIPNAME.otp.cpu0   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu0
 
 if {![using_hla]} {
        # if srst is not fitted use SYSRESETREQ to
        # perform a soft reset
-       cortex_m reset_config sysresetreq
+       $_CHIPNAME.cpu0 cortex_m reset_config sysresetreq
 }
 
-$_TARGETNAME configure -event reset-init {
+$_CHIPNAME.cpu0 configure -event reset-init {
        # CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.
        # Configure system to use MSI 24 MHz clock, compliant with VOS default 
Range1.
        # 2 WS compliant with VOS=Range1 and 24 MHz.
@@ -80,12 +97,12 @@ $_TARGETNAME configure -event reset-init {
        adapter speed 4000
 }
 
-$_TARGETNAME configure -event reset-start {
+$_CHIPNAME.cpu0 configure -event reset-start {
        # Reset clock is MSI (4 MHz)
        adapter speed 500
 }
 
-$_TARGETNAME configure -event examine-end {
+$_CHIPNAME.cpu0 configure -event examine-end {
        # Enable debug during low power modes (uses more power)
        # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP
        mmw 0xE0042004 0x00000007 0
@@ -93,8 +110,78 @@ $_TARGETNAME configure -event examine-end {
        # Stop watchdog counters during halt
        # DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP
        mmw 0xE004203C 0x00001800 0
+       
+       set _CHIPNAME [stm32wlx_get_chipname]
+       if {[set $_CHIPNAME.WKUP_CM0P]} {
+               stm32wlx_wkup_cm0p
+       }       
 }
 
-$_TARGETNAME configure -event trace-config {
+$_CHIPNAME.cpu0 configure -event trace-config {
        # nothing to do
 }
+
+if {[set $_CHIPNAME.DUAL_CORE]} {
+       target create $CHIPNAME.cpu1 cortex_m -endian little -dap $CHIPNAME.dap 
-ap-num 1
+
+       $_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM0 
-work-area-size $_WORKAREASIZE -work-area-backup 0
+
+       flash bank $_CHIPNAME.flash.cpu1 stm32l4x 0x08000000 0 0 0 
$_CHIPNAME.cpu1
+       flash bank $_CHIPNAME.otp.cpu1   stm32l4x 0x1fff7000 0 0 0 
$_CHIPNAME.cpu1
+       
+       if {![using_hla]} {
+               # if srst is not fitted use SYSRESETREQ to
+               # perform a soft reset
+               $_CHIPNAME.cpu1 cortex_m reset_config sysresetreq
+       }
+       
+       proc stm32wlx_wkup_cm0p {} {
+               set _CHIPNAME [stm32wlx_get_chipname]
+               
+               # enable CPU2 boot after reset and after wakeup from Stop or 
Standby mode
+               # PWR_CR4 |= C2BOOT
+               stm32wlx_mmw $_CHIPNAME.cpu0 0x5800040C 0x00008000 0
+       }
+}
+
+# get _CHIPNAME from current target
+proc stm32wlx_get_chipname {} {
+       set t [target current]
+       set sep [string last "." $t]
+       if {$sep == -1} {
+               return $t
+       }
+       return [string range $t 0 [expr $sep - 1]]
+}
+
+# like mrw, but with target selection
+proc stm32wlx_mrw {used_target reg} {
+       set value ""
+       $used_target mem2array value 32 $reg 1
+       return $value(0)
+}
+
+# like mmw, but with target selection
+proc stm32wlx_mmw {used_target reg setbits clearbits} {
+       set old [stm32wlx_mrw $used_target $reg]
+       set new [expr ($old & ~$clearbits) | $setbits]
+       $used_target mww $reg $new
+}
+
+# Make sure that cpu0 is selected
+targets $_CHIPNAME.cpu0
+
+# Common knowledges tells JTAG speed should be <= F_CPU/6.
+# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on
+# the safe side.
+#
+# Note that there is a pretty wide band where things are
+# more or less stable, see http://openocd.zylin.com/#/c/3366/
+adapter speed 500
+
+adapter srst delay 100
+if {[using_jtag]} {
+       jtag_ntrst_delay 100
+}
+
+reset_config srst_nogate

-- 


_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to