PCM Hammer P12 development
- antus
- Site Admin
- Posts: 9009
- 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
Im keen to start playing this game. My P12 has transited through 4 US states, cleared the customs house and just left the country. Dont know yet if its coming by ship or air. To quote Tazzi "Impatiently taps foot...."
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
Re: PCM Hammer P12 development
To sum,
Chip ID
Chip Erase
Chip Write
PCM Hammer kernel diffs,
Chip ID
Code: Select all
asm("ORI #0x700, %SR");
SIM_CSOR0 = 0xF322;
COMMAND_REG_AAA = 0xAAAA;
COMMAND_REG_554 = 0x5555;
COMMAND_REG_AAA = 0x9090;
Code: Select all
asm("ORI #0x700, %SR");
SIM_CSOR0 |= 0x4;
COMMAND_REG_AAA = 0xAAAA;
COMMAND_REG_554 = 0x5555;
COMMAND_REG_AAA = 0x8080;
COMMAND_REG_AAA = 0xAAAA;
COMMAND_REG_554 = 0x5555;
*flashBase = 0x3030;
Code: Select all
asm("ORI #0x700, %SR");
SIM_CSOR0 |= 0x4;
COMMAND_REG_AAA = 0xAAAA;
COMMAND_REG_554 = 0x5555;
COMMAND_REG_AAA = 0xA0A0;
*address = value;
Code: Select all
diff -u Kernels/common-readwrite.c ../Test Builds/P12/Kernels/Kernels/common-readwrite.c
--- Kernels/common-readwrite.c 2021-01-29 09:32:23.970935000 -0500
+++ ../Test Builds/P12/Kernels/Kernels/common-readwrite.c 2022-03-21 10:43:41.713417000 -0400
@@ -65,7 +65,11 @@
void SendWriteSuccess(unsigned char code)
{
// Send response
+#if defined P12
+ MessageBuffer[0] = 0x6C;
+#else
MessageBuffer[0] = 0x6D;
+#endif
MessageBuffer[1] = 0xF0;
MessageBuffer[2] = 0x10;
MessageBuffer[3] = 0x76;
@@ -76,7 +80,11 @@
void SendWriteFail(unsigned char callerError, unsigned char flashError)
{
+#if defined P12
+ MessageBuffer[0] = 0x6C;
+#else
MessageBuffer[0] = 0x6D;
+#endif
MessageBuffer[1] = 0xF0;
MessageBuffer[2] = 0x10;
MessageBuffer[3] = 0x7F;
diff -u Kernels/common.c ../Test Builds/P12/Kernels/Kernels/common.c
--- Kernels/common.c 2022-01-15 14:51:22.409295399 -0500
+++ ../Test Builds/P12/Kernels/Kernels/common.c 2022-03-21 10:16:13.150448000 -0400
@@ -26,8 +26,12 @@
{
WATCHDOG1 = 0x55;
WATCHDOG1 = 0xAA;
+#if defined P12
+ WATCHDOG2 ^= 0x80;
+#else
WATCHDOG2 &= 0x7F;
WATCHDOG2 |= 0x80;
+#endif
}
///////////////////////////////////////////////////////////////////////////////
diff -u Kernels/common.h ../Test Builds/P12/Kernels/Kernels/common.h
--- Kernels/common.h 2021-12-19 17:41:26.237953561 -0500
+++ ../Test Builds/P12/Kernels/Kernels/common.h 2022-03-12 09:45:01.878596000 -0500
@@ -15,14 +15,34 @@
typedef int int32_t;
#ifndef DLC_CONFIGURATION
- #define DLC_CONFIGURATION (*(unsigned char *)0x00FFF600)
- #define DLC_INTERRUPTCONFIGURATION (*(unsigned char *)0x00FFF606)
- #define DLC_TRANSMIT_COMMAND (*(unsigned char *)0x00FFF60C)
- #define DLC_TRANSMIT_FIFO (*(unsigned char *)0x00FFF60D)
- #define DLC_STATUS (*(unsigned char *)0x00FFF60E)
- #define DLC_RECEIVE_FIFO (*(unsigned char *)0x00FFF60F)
- #define WATCHDOG1 (*(unsigned char *)0x00FFFA27)
- #define WATCHDOG2 (*(unsigned char *)0x00FFD006)
+ #if defined P01
+ #define DLC_CONFIGURATION (*(unsigned char *)0x00FFF600)
+ #define DLC_INTERRUPTCONFIGURATION (*(unsigned char *)0x00FFF606)
+ #define DLC_TRANSMIT_COMMAND (*(unsigned char *)0x00FFF60C)
+ #define DLC_TRANSMIT_FIFO (*(unsigned char *)0x00FFF60D)
+ #define DLC_STATUS (*(unsigned char *)0x00FFF60E)
+ #define DLC_RECEIVE_FIFO (*(unsigned char *)0x00FFF60F)
+ #define WATCHDOG1 (*(unsigned char *)0x00FFFA27)
+ #define WATCHDOG2 (*(unsigned char *)0x00FFD006)
+ #elif defined P04
+ #define DLC_CONFIGURATION (*(unsigned char *)0x00FFE800)
+ #define DLC_INTERRUPTCONFIGURATION (*(unsigned char *)0x00FFE800)
+ #define DLC_TRANSMIT_COMMAND (*(unsigned char *)0x00FFE800)
+ #define DLC_TRANSMIT_FIFO (*(unsigned char *)0x00FFE801)
+ #define DLC_STATUS (*(unsigned char *)0x00FFE800)
+ #define DLC_RECEIVE_FIFO (*(unsigned char *)0x00FFE801)
+ #define WATCHDOG1 (*(unsigned char *)0x00FFFA27)
+ #define WATCHDOG2 (*(unsigned char *)0x00FFC006)
+ #elif defined P12
+ #define DLC_CONFIGURATION (*(unsigned char *)0x00FFF600)
+ #define DLC_INTERRUPTCONFIGURATION (*(unsigned char *)0x00FFF606)
+ #define DLC_TRANSMIT_COMMAND (*(unsigned char *)0x00FFF60C)
+ #define DLC_TRANSMIT_FIFO (*(unsigned char *)0x00FFF60D)
+ #define DLC_STATUS (*(unsigned char *)0x00FFF60E)
+ #define DLC_RECEIVE_FIFO (*(unsigned char *)0x00FFF60F)
+ #define WATCHDOG1 (*(unsigned char *)0x00FFFA55)
+ #define WATCHDOG2 (*(unsigned char *)0x00FFFA21)
+ #endif
#endif
///////////////////////////////////////////////////////////////////////////////
diff -u Kernels/flash-amd.c ../Test Builds/P12/Kernels/Kernels/flash-amd.c
--- Kernels/flash-amd.c 2020-11-23 13:52:17.375198000 -0500
+++ ../Test Builds/P12/Kernels/Kernels/flash-amd.c 2022-03-21 15:56:59.900184000 -0400
@@ -13,11 +13,15 @@
///////////////////////////////////////////////////////////////////////////////
uint32_t Amd_GetFlashId()
{
+#if defined P12
+ SIM_CSOR0 = 0xF322;
+#else
SIM_CSBAR0 = 0x0007;
SIM_CSORBT = 0x6820;
// Switch to flash into ID-query mode.
SIM_CSOR0 = 0x7060;
+#endif
COMMAND_REG_AAA = 0xAAAA;
COMMAND_REG_554 = 0x5555;
COMMAND_REG_AAA = 0x9090;
@@ -30,7 +34,11 @@
// Switch back to standard mode.
FLASH_BASE = READ_ARRAY_COMMAND;
+#if defined P12
+ SIM_CSOR0 = 0xA332;
+#else
SIM_CSOR0 = 0x1060;
+#endif
return id;
}
@@ -46,7 +54,11 @@
uint16_t volatile * flashBase = (uint16_t*)address;
// Tell the chip to erase the given block.
+#if defined P12
+ SIM_CSOR0 |= 0x4;
+#else
SIM_CSOR0 = 0x7060;
+#endif
COMMAND_REG_AAA = 0xAAAA;
COMMAND_REG_554 = 0x5555;
COMMAND_REG_AAA = 0x8080;
@@ -100,7 +112,11 @@
// Return to array mode.
*flashBase = 0xF0F0;
*flashBase = 0xF0F0;
+#if defined P12
+ SIM_CSOR0 = 0xA332;
+#else
SIM_CSOR0 = 0x1060;
+#endif
return status;
}
@@ -124,7 +140,11 @@
if (!testWrite)
{
+#if defined P12
+ SIM_CSOR0 |= 0x4;
+#else
SIM_CSOR0 = 0x7060;
+#endif
COMMAND_REG_AAA = 0xAAAA;
COMMAND_REG_554 = 0x5555;
COMMAND_REG_AAA = 0xA0A0;
@@ -154,7 +174,11 @@
{
*address = 0xF0F0;
*address = 0xF0F0;
+#if defined P12
+ SIM_CSOR0 = 0xA332;
+#else
SIM_CSOR0 = 0x1060;
+#endif
}
return errorCode;
@@ -167,8 +191,13 @@
unsigned short* address = (unsigned short*)startAddress;
*address = 0xF0F0;
*address = 0xF0F0;
+#if defined P12
+ SIM_CSOR0 = 0xA332;
+#else
SIM_CSOR0 = 0x1060;
+#endif
}
return 0;
}
+
diff -u Kernels/flash.h ../Test Builds/P12/Kernels/Kernels/flash.h
--- Kernels/flash.h 2020-12-10 18:38:49.096283000 -0500
+++ ../Test Builds/P12/Kernels/Kernels/flash.h 2022-03-12 10:03:11.058439000 -0500
@@ -2,7 +2,11 @@
// Functions for erasing and writing flash
///////////////////////////////////////////////////////////////////////////////
-#define SIM_BASE 0x00FFFA00
+#if defined P12
+ #define SIM_BASE 0x00FFFA30
+#else
+ #define SIM_BASE 0x00FFFA00
+#endif
#define SIM_CSBARBT (*(unsigned short *)(SIM_BASE + 0x48)) // CSRBASEREG, boot chip select, chip select base addr boot ROM reg,
// must be updated to $0006 on each update of flash CE/WE states
#define SIM_CSORBT (*(unsigned short *)(SIM_BASE + 0x4a)) // CSROPREG, Chip select option boot ROM reg., $6820 for normal op
@@ -54,8 +58,10 @@
uint8_t Intel_WriteToFlash(unsigned int payloadLengthInBytes, unsigned int startAddress, unsigned char *payloadBytes, int testWrite);
// Functions prefixed with Amd1024 work with this chip ID
-#define FLASH_ID_AMD_1024 0x00012258
+#define FLASH_ID_AMD_AM29BL802C 0x00012281 // AM29BL802C
+#define FLASH_ID_AMD_1024 0x00012258
uint32_t Amd_GetFlashId();
uint8_t Amd_EraseBlock(uint32_t address);
uint8_t Amd_WriteToFlash(unsigned int payloadLengthInBytes, unsigned int startAddress, unsigned char *payloadBytes, int testWrite);
+
diff -u Kernels/write-kernel.c ../Test Builds/P12/Kernels/Kernels/write-kernel.c
--- Kernels/write-kernel.c 2022-03-12 09:09:44.324447000 -0500
+++ ../Test Builds/P12/Kernels/Kernels/write-kernel.c 2022-03-21 15:06:55.970887000 -0400
@@ -168,7 +168,11 @@
{
ElmSleep();
+#if defined P12
+ uint8_t *osid = (uint8_t*)0x8004;
+#else
uint8_t *osid = (uint8_t*)0x504;
+#endif
MessageBuffer[0] = 0x6C;
MessageBuffer[1] = 0xF0;
@@ -198,6 +202,7 @@
break;
case FLASH_ID_AMD_1024:
+ case FLASH_ID_AMD_AM29BL802C: // P12 1m
status = Amd_EraseBlock(address);
break;
@@ -267,6 +275,7 @@
return Intel_WriteToFlash(payloadLengthInBytes, startAddress, payloadBytes, testWrite);
case FLASH_ID_AMD_1024:
+ case FLASH_ID_AMD_AM29BL802C: // P12 1m
return Amd_WriteToFlash(payloadLengthInBytes, startAddress, payloadBytes, testWrite);
default:
@@ -293,10 +302,12 @@
switch (MessageBuffer[3])
{
+#if !defined P12
case 0x20:
LongSleepWithWatchdog();
Reboot(0xCC000000 | iterations);
break;
+#endif
case 0x34:
HandleWriteRequestMode34();
@@ -459,9 +472,20 @@
lastMessage = iterations;
lastActivity = iterations;
+#if defined P12
+ // Did the tool just request a reboot?
+ if (MessageBuffer[3] == 0x20)
+ {
+ // Yes
+ break;
+ }
+#endif
+
ProcessMessage(iterations);
}
+#if !defined P12
// This shouldn't happen. But, just in case...
Reboot(0xFF000000 | iterations);
+#endif
}
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!
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!
Re: PCM Hammer P12 development
Apparently my understanding/translation of the following is failing ...
If 0x00FFFA7C = 0x00000004, What is actually written to 0x00FFFA7C ??
The whole block it is out of,
Code: Select all
ROM:00FF2052 move.w (word_FFFFFA7C).w,dword_FFFFFFF8(a6)
ROM:00FF2058 andi.b #$F8,-7(a6)
ROM:00FF205E ori.b #5,-7(a6)
ROM:00FF2064 move.w dword_FFFFFFF8(a6),(word_FFFFFA7C).w
The whole block it is out of,
Code: Select all
ROM:00FF203A sub_FF203A:
ROM:00FF203A nop
ROM:00FF203C link a6,#$FFF8
ROM:00FF2040 move.w (word_FFFFFA7E).w,word_FFFFFFFC(a6)
ROM:00FF2046 bset #4,word_FFFFFFFC(a6)
ROM:00FF204C move.w word_FFFFFFFC(a6),(word_FFFFFA7E).w
ROM:00FF2052 move.w (word_FFFFFA7C).w,dword_FFFFFFF8(a6)
ROM:00FF2058 andi.b #$F8,-7(a6)
ROM:00FF205E ori.b #5,-7(a6)
ROM:00FF2064 move.w dword_FFFFFFF8(a6),(word_FFFFFA7C).w
ROM:00FF206A unlk a6
ROM:00FF206C rts
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!
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!
Re: PCM Hammer P12 development
Read word fa7c to a word buffer , example 0406
Take first byte 04 and apply
andi.b #$F8 [11111000 * 00000100 =0] [basically clear first 3 bits]
ori.b #5 [add 00000101 to 0 = 5]
buffer= 0506
Than write from buffer to fa7c.
You are done
Take first byte 04 and apply
andi.b #$F8 [11111000 * 00000100 =0] [basically clear first 3 bits]
ori.b #5 [add 00000101 to 0 = 5]
buffer= 0506
Than write from buffer to fa7c.
You are done
Re: PCM Hammer P12 development
kur4o,
Thank you for the math lesson, I'm sure some reader will learn something, unfortunately that reader is not me!
I know it's hard for you that are capable of doing the math to understand that some of us are not capable and don't get it!
In your example, the word buffer would be 0004.
Thank you for the math lesson, I'm sure some reader will learn something, unfortunately that reader is not me!
I know it's hard for you that are capable of doing the math to understand that some of us are not capable and don't get it!
In your example, the word buffer would be 0004.
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!
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!
Re: PCM Hammer P12 development
Actually it is not that easy as it looks , especially on some frankestein math conversions.
Take 0004 as read from fffffa7c
split in 2 bytes 00 and 04
00 will be multiplied with f8, than result will be added with 5
So it will look like
buffer=00 04 convert first byte, second byte stays the same
=(00*f8)+5=05
so final result will be
05 04
that needs to be written back to FFFFFa7c
Take 0004 as read from fffffa7c
split in 2 bytes 00 and 04
00 will be multiplied with f8, than result will be added with 5
So it will look like
buffer=00 04 convert first byte, second byte stays the same
=(00*f8)+5=05
so final result will be
05 04
that needs to be written back to FFFFFa7c
Re: PCM Hammer P12 development
I believe it translates to this which is a bit more readable:
Assuming I have this right...
A7E is bcsor1.. and enabling bit 4 is related to memory boundary.
A7C is bcsbar... clearing the bits is just to reset this setting, and enabling bits 0 and 2 (101) means block size 2MB.
Block size means the "extent of the address space from its space address". So it doesnt necessarily mean anything about the connected flashes memory size, just that the cpu is setup to deal with up to 2MB.
Code: Select all
bset #4, (FFFFFA7E) ;Set bit 4
move.w (FFFFFA7C), D1 ;Move value from A7C into D1
andi.w #$FFF8, D1 ; clear bits 0,1,2.
ori.w #5,D1 ;enable bits 0,2
move.w D1, (FFFFFA7C) ;save back to A7C
Assuming I have this right...
A7E is bcsor1.. and enabling bit 4 is related to memory boundary.
A7C is bcsbar... clearing the bits is just to reset this setting, and enabling bits 0 and 2 (101) means block size 2MB.
Block size means the "extent of the address space from its space address". So it doesnt necessarily mean anything about the connected flashes memory size, just that the cpu is setup to deal with up to 2MB.
Your Local Aussie Reverse Engineer
Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726

Contact for Software/Hardware development and Reverse Engineering
Site:https://www.envyouscustoms.com
Mob:+61406 140 726

Re: PCM Hammer P12 development
Maybe we are not as far along as we thought ...
We were able to erase the calibration sector starting at 020000 with a specific kernel version, we call it .11.
Before and after bins are in this thread ... they show it's clearly a proper erase of the right sector.
Since the PCM was recovered with the Tech2, we have been getting successful erase responses.
Ok, this kernel version is stuffed ... I whip out the kernel that successfully erased previously (we call it .11), proceed to erase the same sector, nothing just more corruption!
The moral of the story ... We obviously don't have erase working either!
We were able to erase the calibration sector starting at 020000 with a specific kernel version, we call it .11.
Before and after bins are in this thread ... they show it's clearly a proper erase of the right sector.
Since the PCM was recovered with the Tech2, we have been getting successful erase responses.
However looking at the bin files, they are NOT erased, the range is corrupted, not erased (not all FF's).[12:01:40:886] TX: 6C 10 F0 3D 05 02 00 00
[12:01:40:902] RX: 6C F0 10 7D 05 00 00
Ok, this kernel version is stuffed ... I whip out the kernel that successfully erased previously (we call it .11), proceed to erase the same sector, nothing just more corruption!
The moral of the story ... We obviously don't have erase working either!
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!
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!
Re: PCM Hammer P12 development
Is there any chance that voltage is dipping during the erase?
Corruption sounds more like an electrical problem than a software problem.
I'm just guessing though.
Corruption sounds more like an electrical problem than a software problem.
I'm just guessing though.
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!
Re: PCM Hammer P12 development
The erase command seems accurate, I think it is time of waiting till the erase is done, Usually 2-3 seconds per segment.
You can also check if the erase is done with reading register where 3030 is loaded, And wait for specific response.
This is the check when erase is done. test bit5 on d5 or test on plus. Not sure which one is success.
Some example
You want to erase segment 20000
you push 20000 to a0 register
Than push 3030 to a0 register
Than read a word from a0[push to d5] and do a check wait some time with COP and repeat till erase is done confirmation.
You can also check if the erase is done with reading register where 3030 is loaded, And wait for specific response.
Code: Select all
RAM:FFFF2110 loc_FFFF2110: ; CODE XREF: eraASE1_sub_FFFF2070+8Cj
RAM:FFFF2110 tst.b d5
RAM:FFFF2112 bpl.s loc_FFFF2118
RAM:FFFF2114 moveq #1,d4
RAM:FFFF2116 bra.s loc_FFFF2130
RAM:FFFF2118 ; ---------------------------------------------------------------------------
RAM:FFFF2118
RAM:FFFF2118 loc_FFFF2118: ; CODE XREF: eraASE1_sub_FFFF2070+A2j
RAM:FFFF2118 btst #5,d5
RAM:FFFF211C beq.w loc_FFFF20AC
Some example
You want to erase segment 20000
you push 20000 to a0 register
Than push 3030 to a0 register
Than read a word from a0[push to d5] and do a check wait some time with COP and repeat till erase is done confirmation.