Close

wherein we discover with some amount of certainty...

A project log for operation: Learn The MIPS (PIC32MX1xx/2xx/370)

Having been exclusive to a certain uC-line for over a decade, it's time to learn something new (and port commonCode!)... Enter MIPS

eric-hertzEric Hertz 07/12/2015 at 06:410 Comments

...that the world doesn't really exist. Or something like that.

Regardless:

Apparently, the trick to getting openOCD to use the fast-writing method is to hack it in two ways.

THESE ARE 'INSTRUCTIONS' TO SPEED UP PIC32 PROGRAMMING

(Without them, it takes nearly 10 MINUTES to flash! With, just a handful of seconds.)


First: Apparently there's a test that determines whether the fast-write data buffer is safe...

This test, apparently, is faulty...

basically it tests: "offset + size", whereas it should test "offset + size -1"

(say the offset/start address is 0, and the size is 8 bytes, then it thinks the *last-used* byte is 8, rather than byte 7...)

Fine, bad-programmer, right? Lucky, I suppose; musta been using some set-up wherein the data-buffer was somehow created not-immediately-after the working-buffer... 'spose it's plausible. Regardless, unless these buffers use 'null-termination' this is a glaring mistake..

Second: After that's fixed, there's a new "register 'a0' not defined" message... which is special... because, apparently, this message... only appears after you fix the above, right...?

But, no, it comes back to haunt us again later...

For now, yeah, apparently the MIPS32 registers are listed as "r0"-"r31", but should be given more-relevent names, one of which is "r7" which should be "a0" (as I recall).

I guess our friend "Serge" fixed this way back in 0.60, but somehow it came back...?

http://sourceforge.net/p/openocd/mailman/message/28333633/

Regardless, this is the weird part...

Fixing that doesn't fix the problem... fast-write still doesn't work. I can't recall the message off-hand, but somehow it led me to look into fixes, wherein we find... wait, just a minute, I gotta point this out: Without Fast-Write mode, it takes TEN MINUTES to flash 64kb... and my program's really only like 2k... so there's that, too... TEN FRIGGIN' MINUTES every time I make a code-change. Yeah, no.

So, the problem, no we're not yet at the "weird part" yet... I'll get to it, Promise...

Anyways, the new weird message leads to this page:

http://openocd.zylin.com/#/c/977/

which says "abandoned" because, apparently "Not needed. We can play with adapter_khz and/or scan_delay in queued mode to make it work nearly safe and faster."

Ohhh, OK, so all's I hads to do's was adjust adapter_khz... apparently it was too fast, the program running on the pic for fast-write was executing too slowly, and my fast 4000khz adapter_khz was too fast, causing polling of whether the program had completed to fail... I think I get it...

Fine, back to the Unhacked version of openOCD-0.90... the freshly-compiled version, straight from the source... this time with adapter_khz of 400, rather'n my old 4000

And, low-and-behold: "falling back to non fast-write" as well as "register 'a0' not defined"

Whoa, now, wait a minute... the 'a0' issue was due to the fact that fast-write is *being executed*, no? That's how I understood it... that 'a0' thing was only happening *because* I fixed the overlapping-memory-test, before... when that overlapping-memory-test failed, it resorted to "non fast write" mode... So, then, when I fixed the overlapping-memory-test, it was then *able* to *attempt* fast-write, wherein we discovered the 'a0' bug in the 'fast-write' algorithm... RIGHT?

So, then, why does changing adapter_khz to 400 somehow *ignore* the overlapping-memory-test failure in the original version, and *go into fast-write mode*?!

Alright, I dunno... So, adapter_khz 4000 works with *slow-writing* on the default 0.90

400 causes the 'a0' issue to appear, on the default 0.90

OK

And in the hacked-version...?

adapter_khz 4000 results in falling-back to non-fast-write, and if I recall, actually fails... No, that ain't right... it results in the 'a0' message... no, that ain't right, either, 'cause I just fixed that... so, what was the weird error that caused me to look into the "zylin" page...? I can't recall, but there was some weird message that caused me to look into the "zylin" page... and that page basically said to try a slower adapter_khz, and my having-done-so resulted in a REALLY FAST WRITE.

So, two changes were necessary, in openOCD's source-code:

First: fix that overlapping-memory-test, so that fast-write can execute (using the memory-buffer tested for overlap)

Second: replace the 'r' registers with their better names... so that, apparently, the code that's supposed to run for "fast-write" mode, can execute *at all*...

Then, of course, the third step is to change adapter_khz to 400 (from 4000)

Fine.

For posterity: Here's where we're at... this world doesn't exist. Logic is irrelevent. Programming is bullshit, code... code only functions when you don't understand *how* it functions. Or something. I'm ready for the next level, so I'm not going to write this up in any easier format, 'cause, frankly, even if I did, this wouldn't help you, because the universe, or whatever it is, would find a completely different path-of-confusion for you.

So, here's the diffs:

diff -x .DS_Store -r openocd-0.9.0_fresh/src/target/mips32.c openocd-0.9.0_hacked/src/target/mips32.c
47a48
> #if 0
163a165,214
> #else
> //meh:
> // per:
> // http://sourceforge.net/p/openocd/mailman/message/28333633/
> static const struct {
> 	unsigned id;
> 	const char *name;
> 	enum reg_type type;
> 	const char *group;
> 	const char *feature;
> 	int flag;
> } mips32_regs[] = {
> 	{  0,  "zero", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  1,  "at", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  2,  "v0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  3,  "v1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  4,  "a0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  5,  "a1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  6,  "a2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  7,  "a3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  8,  "t0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{  9,  "t1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 10,  "t2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 11,  "t3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 12,  "t4", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 13,  "t5", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 14,  "t6", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 15,  "t7", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 16, "s0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 17, "s1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 18, "s2", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 19, "s3", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 20, "s4", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 21, "s5", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 22, "s6", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 23, "s7", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 24, "t8", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 25, "t9", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 26, "k0", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 27, "k1", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 28, "gp", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 29, "sp", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 30, "fp", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 31, "ra", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 32, "status", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
> 	{ 33, "lo", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 34, "hi", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
> 	{ 35, "badvaddr", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
> 	{ 36, "cause", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cp0", 0 },
> 	{ 37, "pc", REG_TYPE_INT, NULL, "org.gnu.gdb.mips.cpu", 0 },
164a216,285
> 	{ 38,  "f0", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 39,  "f1", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 40,  "f2", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 41,  "f3", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 42,  "f4", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 43,  "f5", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 44,  "f6", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 45,  "f7", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 46,  "f8", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 47,  "f9", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 48, "f10", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 49, "f11", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 50, "f12", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 51, "f13", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 52, "f14", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 53, "f15", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 54, "f16", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 55, "f17", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 56, "f18", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 57, "f19", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 58, "f20", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 59, "f21", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 60, "f22", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 61, "f23", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 62, "f24", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 63, "f25", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 64, "f26", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 65, "f27", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 66, "f28", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 67, "f29", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 68, "f30", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 69, "f31", REG_TYPE_IEEE_SINGLE, NULL,
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 70, "fcsr", REG_TYPE_INT, "float",
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> 	{ 71, "fir", REG_TYPE_INT, "float",
> 		"org.gnu.gdb.mips.fpu", MIPS32_GDB_DUMMY_FP_REG },
> };
> #endif
diff -x .DS_Store -r openocd-0.9.0_fresh/src/target/mips_m4k.c openocd-0.9.0_hacked/src/target/mips_m4k.c
1171,1172c1171,1186
< 	if (address <= fast_data_area->address + fast_data_area->size &&
< 			fast_data_area->address <= address + count) {
---
> 	typeof(fast_data_area->address) fd_addr = fast_data_area->address;
> 
> 	typeof(fd_addr) fd_lastAddr = fd_addr + fast_data_area->size -1;
> 
> 	typeof(address) lastAddr = address + count -1;
> 
> 	//meh:
> 	//THE ABOVE CAN'T BE RIGHT, right?
> 	// lastAddr shouldn't be address + count,
> 	//  otherwise, we'd have e.g. 0x00 + 0x08 = 0x08 = lastAddr
> 	//  but the lastAddress SHOULD be 0x07... No?
> 
> 	//if ( (address <= (fast_data_area->address + fast_data_area->size))
> 	// &&  (fast_data_area->address <= (address + count)) )
> 	if ( ( address <= fd_lastAddr ) && ( fd_addr <= lastAddr ) )
> 	{
1176a1191,1194
> 		LOG_ERROR("fast_data: (0x%8.8"PRIx32"-0x%8.8"PRIx32").",
> 				fd_addr, fd_lastAddr);
> 		LOG_ERROR("address:   (0x%8.8"PRIx32"-0x%8.8"PRIx32").",
> 				address, lastAddr);

Discussions