PCM Hammer P12 development

They go by many names, P01, P59, VPW, '0411 etc. Also covering E38 and newer here.
User avatar
antus
Site Admin
Posts: 8292
Joined: Sat Feb 28, 2009 8:34 pm
cars: TX Gemini 2L Twincam
TX Gemini SR20 18psi
Datsun 1200 Ute
Subaru Blitzen '06 EZ30 4th gen, 3.0R Spec B
Contact:

Re: PCM Hammer P12 development

Post by antus »

dont need payloadarray or flasharray, just cast the pointers you already have when you use them. the pointers contain the same address value, and the type is only for the compiler.
can also use >>1 instead of /2 but I think the original kernel is also /2. because its binary a right shift 1 bit is equivalent to divide by 2 but a lot faster.
Have you read the FAQ? For lots of information and links to significant threads see here: http://pcmhacking.net/forums/viewtopic.php?f=7&t=1396
User avatar
Gampy
Posts: 2333
Joined: Sat Dec 15, 2018 7:38 am

Re: PCM Hammer P12 development

Post by Gampy »

Nice to know thank you!

All stock PcmHacks kernel code except for,

Code: Select all

uint8_t Amd_WriteToFlash(unsigned int payloadLengthInBytes, unsigned int startAddress, unsigned char *payloadBytes, int testWrite)
{
	char errorCode = 0;
	unsigned short status;
+	unsigned short saveFA50 = (*(unsigned short *)(0xFFFFFA50));

	unsigned short* payloadArray = (unsigned short*) payloadBytes;
	unsigned short* flashArray = (unsigned short*) startAddress;

	for (unsigned index = 0; index < payloadLengthInBytes / 2; index++)
	{
		unsigned short volatile  *address = &(flashArray[index]);
		unsigned short value = payloadArray[index];

		if (!testWrite)
		{
+#if defined P12
+			(*(unsigned short *)(0xFFFFFA50)) &= 0xFEFF;
+			SIM_CSOR0 |= 0x4;
+#else
			SIM_CSOR0 = 0x7060;
+#endif
			COMMAND_REG_AAA = 0xAAAA;
			COMMAND_REG_554 = 0x5555;
			COMMAND_REG_AAA = 0xA0A0;
			*address = value;
		}

		char success = 0;
		for(int iterations = 0; iterations < 0x1000; iterations++)
		{
			ScratchWatchdog();

			uint16_t read = testWrite ? value : *address;

			if (read == value)
			{
				success = 1;
				break;
			}
		}

		if (!success)
		{
			// Return flash to normal mode and return the error code.
			errorCode = 0xAA;

			if (!testWrite)
			{
				*address = 0xF0F0;
				*address = 0xF0F0;
+#if defined P12
+				(*(unsigned short *)(0xFFFFFA50)) = saveFA50;
+				SIM_CSOR0 = 0xA332;
+#else
				SIM_CSOR0 = 0x1060;
+#endif
			}

			return errorCode;
		}
	}

	if (!testWrite)
	{
		// Return flash to normal mode.
		unsigned short* address = (unsigned short*)startAddress;
		*address = 0xF0F0;
		*address = 0xF0F0;
+#if defined P12
+	(*(unsigned short *)(0xFFFFFA50)) = saveFA50;
+	SIM_CSOR0 = 0xA332;
+#else
	SIM_CSOR0 = 0x1060;
+#endif
	}

	return 0;
}
Intelligence is in the details!

It is easier not to learn bad habits, then it is to break them!

If I was here to win a popularity contest, their would be no point, so I wouldn't be here!
kur4o
Posts: 980
Joined: Sun Apr 10, 2016 9:20 pm

Re: PCM Hammer P12 development

Post by kur4o »

I think I figured Fa50 meaning. It looks to be interrupt register.

From ls1 code

Code: Select all

ori     #$700,sr

Code: Select all

andi    #$F8FF,sr
SO it is safe to use

Code: Select all

ori     #$700,ffffFa50
code at the very start of flash routine and dismiss any other code related to fa50, since factory flash needs interrupts, they are disabled on demand while writing to chip.
User avatar
Gampy
Posts: 2333
Joined: Sat Dec 15, 2018 7:38 am

Re: PCM Hammer P12 development

Post by Gampy »

Currently at the kernel code entry point, there is,

Code: Select all

	// Disable peripheral interrupts
	asm("ORI #0x700, %SR");
I believe the following will do the same thing using the address ...

Code: Select all

  (*(unsigned short *)(0xFFFFFA50)) |= 0x700;
Results from last test,
[12:10:46:006] Writing...
[12:10:46:037] Sending payload with offset 0x0000, start address 0x020000, length 0x0400.
[12:10:46:116] TX: 6D 10 F0 36 00 04 00 02 00 00 . . . Wacked for brevity
[12:10:46:350] RX: 6D F0 10 7F 36 00 AA
Note the AA code, that is the results of the read back test in 'Amd_WriteToFlash(...)'.

Code: Select all

         // Return flash to normal mode and return the error code.
         errorCode = 0xAA;
Intelligence is in the details!

It is easier not to learn bad habits, then it is to break them!

If I was here to win a popularity contest, their would be no point, so I wouldn't be here!
User avatar
NSFW
Posts: 691
Joined: Fri Feb 02, 2018 3:13 pm

Re: PCM Hammer P12 development

Post by NSFW »

Gampy wrote:Currently at the kernel code entry point, there is,

Code: Select all

	// Disable peripheral interrupts
	asm("ORI #0x700, %SR");
I believe the following will do the same thing using the address ...

Code: Select all

  (*(unsigned short *)(0xFFFFFA50)) |= 0x700;
Consider doing something like this in a header file:

Code: Select all

unsigned short* interruptControlRegister = (unsigned short*) 0xFFFFFA50;
const unsigned short DisablePeripheralInterrupts = 0x700;
So you can use it like this:

Code: Select all

*interruptControlRegister |= DisablePeripheralInterrupts;
"interruptControlRegister" might not be the best name, if the same register is used for other things, but you get the idea.

BTW... I haven't been very active lately because I started a new job in November, and it's keeping me really busy. But I have been catching up on this thread periodically and the progress here is really cool! :)
Please don't PM me with technical questions - start a thread instead, and send me a link to it. That way I can answer in public, and help other people who have the same question. Thanks!
User avatar
Gampy
Posts: 2333
Joined: Sat Dec 15, 2018 7:38 am

Re: PCM Hammer P12 development

Post by Gampy »

Awesome, Good luck with the job, Thank you for the input.
Is it necessary for testing ??
Intelligence is in the details!

It is easier not to learn bad habits, then it is to break them!

If I was here to win a popularity contest, their would be no point, so I wouldn't be here!
ScarabEpic22
Posts: 23
Joined: Fri Jan 08, 2021 3:36 am
cars: TrailBlazer SS E67 LS2, Sonic E78 LUV
Location: Seattle, WA, USA

Re: PCM Hammer P12 development

Post by ScarabEpic22 »

bubba2533 wrote:So if I read that correctly then the P12 was used on 4,5, and 6 cylinder engines. Which would be really interesting they all used a common Operating System with different calibrations like the P01/P59 did.
Yes, all Atlas family engines (I4/I5/I6, 2.8/2.9/3.5/3.7/4.2L displacements) used the P12 at some point. I have the theory the reason GM went from P10 -> P12 was to move to a common controller instead of having the I6 use the bespoke P10. (Probably emissions too.)


I did some quick spot checking, looks like the I6 uses a different OS than the I5 (trying to find an I4 VIN to check) for the same 06 MY. The I6 came out of a different vehicle platform (GMT360 vs GMT355) than the I4/I5, so that could be a factor as well.

06 I6 OS progression: 12604440 -> 12606400 -> 12627882
06 I5 OS progression: 12591649 -> 12606375 -> 12627883

All have different calibration segments as well...if it's anything like the P10, a different rear end gear+tire combo from the factory = new segment for transmission and/or speedo.

Note that the latest I5 vs I6 OS' are just 1 digit off...so I'm optimistic there could be some shared/common code. Same notes as to why the updated OS exists too. Hope we can find a good universal OS or 2 to create XDFs for, otherwise there are a TON of OS' that have to be mapped.
User avatar
Tazzi
Posts: 3458
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: PCM Hammer P12 development

Post by Tazzi »

I think Antus is onto it with the andi.w #$FEFF,(word_FFFFFA50).w
P01/P59 have the ori.w #$1,($FFFFE2FA).l (Or bset 0.. same thing)... and I know I cant write without that being done.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3458
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: PCM Hammer P12 development

Post by Tazzi »

Cleaning up what Kur40 put.. looks like it is:

Code: Select all

andi.w  #$FEFF,(FFFFFA50)
bset    #4, (FFFFFA7E) 
move.w (FFFFFA7C), D1
andi.w  #$FFF8, D1  ; only keep bit 3
ori.w    #5,D1      ;enable bits 0,1,2
move.w D1, (FFFFFA7E) 
This could be reduced to:

Code: Select all

andi.w  #$FEFF,(FFFFFA50)
bset    #4, (FFFFFA7E) 
andi.w  #$FFF8, (FFFFFA7C)  ; only keep bit 3
ori.w    #5,(FFFFFA7C)      ;enable bits 0,1,2
At least.. that is my interpretation of:

Code: Select all

andi.w  #$FEFF,(word_FFFFFA50).w
move.w  (word_FFFFFA7E).w,word_FFFFFFFC(a6)
bset    #4,var_4(a6)
move.w  var_4(a6),(word_FFFFFA7E).w
move.w  (word_FFFFFA7C).w,dword_FFFFFFF8(a6)
andi.b  #$F8,dword_FFFFFFF8+1(a6)
ori.b   #5,dword_FFFFFFF8+1(a6)
move.w  dword_FFFFFFF8(a6),(word_FFFFFA7C).

Then looking at the "after programming event", we get:

Code: Select all

bclr    #4,(FFFFFA7E)   ;turn off bit we enabled previously
andi.w #$FEFF,(FFFA50)     ;clear bit 8 (0x100)
ori.w #$100,(FFFA50)     ;enable bit 8 
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
User avatar
Tazzi
Posts: 3458
Joined: Thu May 17, 2012 8:53 pm
cars: VE SS Ute
Location: WA
Contact:

Re: PCM Hammer P12 development

Post by Tazzi »

One thing to note is the FFFA7C does not appear to be changed on the 'after programming', unless it simply has not yet been spotted in the bin
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726
Image
Post Reply