Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.

Commit 94ca0c7

Browse files
committed
tms570 wip: get init working
Signed-off-by: Sean Cross <sean@xobs.io>
1 parent 514b5e0 commit 94ca0c7

3 files changed

Lines changed: 210 additions & 4 deletions

File tree

src/target/cortexar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ bool cortexar_attach(target_s *const target)
968968
target_halt_reason_e reason = TARGET_HALT_RUNNING;
969969
while (!platform_timeout_is_expired(&timeout) && reason == TARGET_HALT_RUNNING)
970970
reason = target_halt_poll(target, NULL);
971-
if (reason != TARGET_HALT_REQUEST) {
971+
if ((reason != TARGET_HALT_REQUEST) && (reason != TARGET_HALT_BREAKPOINT)) {
972972
DEBUG_ERROR("Failed to halt the core\n");
973973
return false;
974974
}

src/target/target_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ struct target {
168168
union {
169169
bool unsafe_enabled;
170170
bool ke04_mode;
171+
bool tms570_flash_initialized;
171172
};
172173

173174
bool attached;

src/target/ti_tms570.c

Lines changed: 208 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,54 @@
22
#include "target.h"
33
#include "target_internal.h"
44
#include "cortexar.h"
5+
#include "buffer_utils.h"
56

6-
#define TMS570_SYS_BASE 0xffffff00U
7-
#define TMS570_SYS_DEVID (TMS570_SYS_BASE + 0xf0U)
8-
#define TMS570_SCM_DEVID_ID_MASK 0x0700fe7fU /* Note: value is swapped since target is BE */
7+
#define TMS570_SYS_BASE 0xFFFFFF00U
8+
#define TMS570_SYS_DEVID (TMS570_SYS_BASE + 0xF0U)
9+
#define TMS570_SCM_DEVID_ID_MASK 0x0700FE7FU /* Note: value is swapped since target is BE */
910
#define TMS570_SCM_REVID_ID_TMS570 0x05004400U /* Note: value is swapped since target is BE */
1011

12+
#define TMS570_OTP_BANK0_MEMORY_INFORMATION 0xF008015CU
13+
#define TMS570_OTP_BANK0_MEMORY_SIZE_MASK 0xFFFFU
14+
1115
/* Base address for the OCRAM regions, including their mirrors (including RETRAM) */
1216
#define TMS570_SRAM_BASE 0x08000000U
1317
#define TMS570_SRAM_ECC_BASE 0x08400000U
1418
#define TMS570_SRAM_SIZE 0x80000U
1519

20+
#define TMS570_FLASH_BASE_ADDR 0x00000000U
21+
#define TMS570_FLASH_SECTOR_ADDR (TMS570_L2FMC_BASE_ADDR + 0x408U)
22+
#define TMS570_FLASH_SECTOR_SIZE
23+
24+
#define TMS570_L2FMC_BASE_ADDR 0xFFF87000U
25+
#define TMS570_L2FMC_FSPRD_ADDR (TMS570_FLASH_BASE_ADDR + 0x4U)
26+
#define TMS570_L2FMC_FMAC_ADDR (TMS570_FLASH_BASE_ADDR + 0x50U)
27+
#define TMS570_L2FMC_FLOCK_ADDR (TMS570_FLASH_BASE_ADDR + 0x64U) /* Undocumented */
28+
#define TMS570_L2FMC_FVREADCT_ADDR (TMS570_FLASH_BASE_ADDR + 0x80U) /* Undocumented */
29+
#define TMS570_L2FMC_FVNVCT_ADDR (TMS570_FLASH_BASE_ADDR + 0x8CU) /* Undocumented */
30+
#define TMS570_L2FMC_FVPPCT_ADDR (TMS570_FLASH_BASE_ADDR + 0x90U) /* Undocumented */
31+
#define TMS570_L2FMC_FVWLCT_ADDR (TMS570_FLASH_BASE_ADDR + 0x94U) /* Undocumented */
32+
#define TMS570_L2FMC_FEFUSE_ADDR (TMS570_FLASH_BASE_ADDR + 0x98U) /* Undocumented */
33+
#define TMS570_L2FMC_FBSTROBES_ADDR (TMS570_FLASH_BASE_ADDR + 0x100U) /* Undocumented */
34+
#define TMS570_L2FMC_FPSTROBES_ADDR (TMS570_FLASH_BASE_ADDR + 0x104U) /* Undocumented */
35+
#define TMS570_L2FMC_FBMODE_ADDR (TMS570_FLASH_BASE_ADDR + 0x108U) /* Undocumented */
36+
#define TMS570_L2FMC_FTCR_ADDR (TMS570_FLASH_BASE_ADDR + 0x10CU) /* Undocumented */
37+
#define TMS570_L2FMC_FSM_WR_ENA_ADDR (TMS570_FLASH_BASE_ADDR + 0x288U)
38+
1639
#define TMS570_OTP_PACKAGE_AND_FLASH_MEMORY_SIZE 0xf008015cU
1740

41+
#define TMS570_OTP_BANK0_BASE 0xF0080000U
42+
#define TMS570_FLASH_OTP_BASE (TMS570_OTP_BANK0_BASE + 0x170)
43+
44+
/*
45+
* Flash functions
46+
*/
47+
static bool tms570_flash_erase(target_flash_s *flash, target_addr_t addr, size_t len);
48+
static bool tms570_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t len);
49+
static bool tms570_flash_prepare(target_flash_s *flash);
50+
static bool tms570_flash_done(target_flash_s *flash);
51+
static bool tms570_flash_initialize(target_s *const target);
52+
1853
bool ti_tms570_probe(target_s *const target)
1954
{
2055
const uint32_t part_id = target_mem32_read32(target, TMS570_SYS_DEVID);
@@ -27,5 +62,175 @@ bool ti_tms570_probe(target_s *const target)
2762
target_add_ram32(target, TMS570_SRAM_BASE, TMS570_SRAM_SIZE);
2863
target_add_ram32(target, TMS570_SRAM_ECC_BASE, TMS570_SRAM_SIZE);
2964

65+
// target_flash_s *flash = calloc(1, sizeof(*flash));
66+
// if (!flash) { /* calloc failed: heap exhaustion */
67+
// DEBUG_ERROR("calloc: failed in %s\n", __func__);
68+
// return false;
69+
// }
70+
71+
tms570_flash_initialize(target);
72+
73+
// flash->start = TMS570_FLASH_BASE_ADDR;
74+
// flash->length = flash_size;
75+
// flash->blocksize = TMS570_FLASH_SECTOR_SIZE;
76+
// flash->writesize = CH579_FLASH_WRITE_SIZE;
77+
// flash->erase = tms570_flash_erase;
78+
// flash->write = tms570_flash_write;
79+
// flash->prepare = tms570_flash_prepare;
80+
// flash->done = tms570_flash_done;
81+
// flash->erased = 0xffU;
82+
// target_add_flash(target, flash);
83+
84+
return true;
85+
}
86+
87+
static uint32_t accumulate(uint32_t arg, const uint32_t val)
88+
{
89+
arg += (val & 0xffffU);
90+
return (arg & 0xffffU) + (arg >> 16);
91+
}
92+
93+
/// The flash configuration data is burned into a special OTP block on the target.
94+
/// This data is hashed with a Fletcher checksum, which has the nice property that
95+
/// it can tell us if the endianness is backwards or if we're not talking to the
96+
/// correct device. The checksum value is stored in the last word of the OTP area.
97+
static bool fletcher_checksum(const uint32_t *const otp_data, const size_t otp_data_count, const uint32_t comparison)
98+
{
99+
uint32_t check_low = 0xffffU;
100+
uint32_t check_high = 0xffffU;
101+
102+
for (size_t i = 0; i < otp_data_count; i++) {
103+
uint32_t word = otp_data[i];
104+
// Accumulate low word
105+
check_low = accumulate(check_low, word);
106+
check_high = accumulate(check_high, check_low);
107+
// Accumulate high word
108+
check_low = accumulate(check_low, word >> 16);
109+
check_high = accumulate(check_high, check_low);
110+
}
111+
112+
uint32_t result = (check_high << 16) | check_low;
113+
DEBUG_TARGET("Comparing result %08" PRIx32 " to check value %08" PRIx32 "\n", result, comparison);
114+
return comparison == result;
115+
}
116+
117+
static bool tms570_flash_initialize(target_s *const target)
118+
{
119+
if (target->tms570_flash_initialized)
120+
return true;
121+
122+
// Read the OTP data out of flash. This is protected with a Fletcher checksum
123+
uint32_t otp_data[12];
124+
for (int i = 0; i < 12; i++) {
125+
const uint32_t value = target_mem32_read32(target, TMS570_FLASH_OTP_BASE + (i * 4));
126+
otp_data[i] = read_be4((const uint8_t *)&value, 0);
127+
DEBUG_TARGET("Flash OTP[0x%08" PRIx32 "]: 0x%08" PRIx32 "\n", TMS570_FLASH_OTP_BASE + (i * 4), otp_data[i]);
128+
}
129+
if (!fletcher_checksum(otp_data, 11, otp_data[11])) {
130+
return false;
131+
}
132+
133+
// Enable all three banks
134+
uint32_t fmac = target_mem32_read32(target, TMS570_L2FMC_FMAC_ADDR);
135+
target_mem32_write32(target, TMS570_L2FMC_FMAC_ADDR, fmac | 7);
136+
137+
// Disable read margin control.
138+
// (Note: previously this set RMBSEL first and then RM0/1, but do both in one write now)
139+
target_mem32_write32(target, TMS570_L2FMC_FSPRD_ADDR, 0);
140+
141+
// Disable the FSM
142+
target_mem32_write32(target, TMS570_L2FMC_FSM_WR_ENA_ADDR, 0);
143+
144+
// Copy some timing values from OTP
145+
uint32_t unk_210 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x210);
146+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x210, (unk_210 & 0xffff0000) | (otp_data[0] >> 16));
147+
uint32_t unk_218 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x218);
148+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x218, (unk_218 & 0xffff0000) | (otp_data[0] & 0xffff));
149+
150+
// Set the 2nd nibble after the first write is completed
151+
uint32_t unk_21c = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x21c);
152+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x21c, (unk_21c & 0xffff00f0) | (otp_data[1] & 0xff0f));
153+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x21c, (unk_21c & 0xffff0000) | (otp_data[1] & 0xffff));
154+
155+
// ???
156+
uint8_t unk_214 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x214);
157+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x214, (unk_214 & 0xffff0fff) | (otp_data[3] & 0xf000));
158+
159+
// ???
160+
uint8_t unk_220 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x220);
161+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x220, (unk_220 & 0xffffff00) | ((otp_data[1] >> 24) & 0xff));
162+
163+
// ???
164+
uint32_t unk_224 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x224);
165+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x224, (unk_224 & 0xffffff00) | ((otp_data[2] >> 16) & 0xff));
166+
167+
// ???
168+
uint16_t unk_268 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x268);
169+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x268, (unk_268 & 0xfffff000) | (otp_data[5] & 0xfff));
170+
171+
// ???
172+
uint16_t unk_26c = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x26c);
173+
target_mem32_write16(
174+
target, TMS570_L2FMC_BASE_ADDR + 0x26c, (unk_26c & 0xfe00ffff) | ((otp_data[8] & 0x1ff) << 16));
175+
176+
// NOTE: This used to be a 16-bit access -- ensure that it's properly swapped
177+
uint16_t unk_270 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x270);
178+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x270, unk_270 & 0xfe00ffff);
179+
180+
uint32_t unk_278 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x278);
181+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x278, (unk_278 & 0xffffff80) | ((otp_data[4] - 1) & 0x7f));
182+
183+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x27c, 0x4500);
184+
185+
// Unlock L2FMC
186+
target_mem32_write32(target, TMS570_L2FMC_FLOCK_ADDR, 0x55aa);
187+
188+
uint32_t fvreadct = target_mem32_read32(target, TMS570_L2FMC_FVREADCT_ADDR);
189+
target_mem32_write32(target, TMS570_L2FMC_FVREADCT_ADDR, (fvreadct & 0xfffffff0) | ((otp_data[10] >> 8) & 0xf));
190+
191+
target_mem32_write32(target, TMS570_L2FMC_FVNVCT_ADDR, 0);
192+
193+
target_mem32_write32(target, TMS570_L2FMC_FBSTROBES_ADDR, 0x00010104);
194+
target_mem32_write32(target, TMS570_L2FMC_FPSTROBES_ADDR, 0x103);
195+
target_mem32_write32(target, TMS570_L2FMC_FBMODE_ADDR, 0);
196+
197+
uint32_t ftcr = target_mem32_read32(target, TMS570_L2FMC_FTCR_ADDR);
198+
target_mem32_write32(target, TMS570_L2FMC_FTCR_ADDR, ftcr & 0xffffff80);
199+
200+
uint32_t fvppct = target_mem32_read32(target, TMS570_L2FMC_FVPPCT_ADDR);
201+
target_mem32_write32(target, TMS570_L2FMC_FVPPCT_ADDR,
202+
(fvppct & 0xffffe0e0) | (((otp_data[9] >> 8) & 0x1f) << 8) | (otp_data[9] & 0x1f));
203+
204+
uint8_t fvwlct = target_mem32_read32(target, TMS570_L2FMC_FVWLCT_ADDR);
205+
target_mem32_write32(target, TMS570_L2FMC_FVWLCT_ADDR, (fvwlct & ~0xf000) | ((otp_data[10] >> 24) & 0xf) << 12);
206+
207+
uint32_t fefuse = target_mem32_read32(target, TMS570_L2FMC_FEFUSE_ADDR);
208+
target_mem32_write32(target, TMS570_L2FMC_FEFUSE_ADDR, (fefuse & 0xffffffe0) | ((otp_data[10] >> 16) & 0x1f));
209+
210+
uint32_t unk_a8 = target_mem32_read32(target, TMS570_L2FMC_BASE_ADDR + 0x0a8);
211+
target_mem32_write32(target, TMS570_L2FMC_BASE_ADDR + 0x0a8, (unk_a8 & 0xffffff00) | ((otp_data[3] >> 16) & 0xff));
212+
213+
target_mem32_write32(target, TMS570_L2FMC_FPSTROBES_ADDR, 0x103);
214+
215+
target_mem32_write32(target, TMS570_L2FMC_FBSTROBES_ADDR, 0x10104);
216+
217+
// Reads as 0x55aa
218+
target_mem32_write32(target, TMS570_L2FMC_FLOCK_ADDR, 0);
219+
220+
// Re-enable the FSM
221+
uint32_t fsm = target_mem32_read32(target, TMS570_L2FMC_FSM_WR_ENA_ADDR);
222+
target_mem32_write32(target, TMS570_L2FMC_FSM_WR_ENA_ADDR, (fsm & 0xfffffff8) | 2);
223+
224+
target->tms570_flash_initialized = true;
30225
return true;
31226
}
227+
228+
static bool tms570_flash_prepare(target_flash_s *flash)
229+
{
230+
target_s *const target = flash->t;
231+
232+
if (!tms570_flash_initialize(target)) {
233+
DEBUG_ERROR("Checksum for OTP values doesn't match!");
234+
return false;
235+
}
236+
}

0 commit comments

Comments
 (0)