Author Topic: Reading firmware out of a mask ROM microcontroller  (Read 4915 times)

0 Members and 1 Guest are viewing this topic.

Offline tru

  • Regular Contributor
  • *
  • Posts: 82
  • Country: gb
Re: Reading firmware out of a mask ROM microcontroller
« Reply #50 on: April 16, 2021, 10:06:06 am »
Forgot to add, the M16C-R5F364A6N MCU is the same setup as with the controller I read from (M30624FGPGP).

Just to reiterate my setup:
- made up a debug header cable and wired as above (except for reset), so on the cable directly wired SCLK, EPM to ground (low) and CNVSS to 5v (high), connected TXD1 and RXD1 to TTL UART/USB
- on the PCB the CE pin is already pulled-up to 5V through a resistor so left that pin untouched
- the ground of TTL UART/USB connected to ground of the controller board (I used multi-meter to make sure the debug header ground is really earth ground!)
- turned on the controller normally (using it's own circuit)
- waited 1 to 2 seconds for MCU to boot the loader
- send the read version command from the PC (this command doesn't need a password ID)
- when working I see VER 4.04 displayed

Noted: I didn't need to toggle the RESET pin low then high, it was left untouched.
« Last Edit: April 16, 2021, 10:13:49 am by tru »
 
The following users thanked this post: canadaboy25

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #51 on: April 17, 2021, 10:10:49 am »
Forgot to add, the M16C-R5F364A6N MCU is the same setup as with the controller I read from (M30624FGPGP).

Just to reiterate my setup:
- made up a debug header cable and wired as above (except for reset), so on the cable directly wired SCLK, EPM to ground (low) and CNVSS to 5v (high), connected TXD1 and RXD1 to TTL UART/USB
- on the PCB the CE pin is already pulled-up to 5V through a resistor so left that pin untouched
- the ground of TTL UART/USB connected to ground of the controller board (I used multi-meter to make sure the debug header ground is really earth ground!)
- turned on the controller normally (using it's own circuit)
- waited 1 to 2 seconds for MCU to boot the loader
- send the read version command from the PC (this command doesn't need a password ID)
- when working I see VER 4.04 displayed

Noted: I didn't need to toggle the RESET pin low then high, it was left untouched.

Ah, so that's where they're hiding all the information.  The hardware manual is what I should've been looking at.

I wired everything up how you specified and sure enough, I was able to read the flash!  My bootloader version number was 1.00.  I had to change the user ID to all FF to get it to read the firmware, but for some reason after that, all 00 worked as well.  Not sure why that is.

So now I have a dump of the firmware, I need to get it disassembled.  I tried following the steps you posted previously but I cannot get the project you posted to load up in HEW.  For some reason it is just blank.  Had a short go at trying to get my bin file loaded in but didn't get very far.  I'll have to try some more to find some documentation on how to use the disassembly feature properly.  That seems to be the main challenge with these MCUs, finding the relevant documentation...

Thanks for helping me get this far!
« Last Edit: April 17, 2021, 10:13:07 am by canadaboy25 »
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline tru

  • Regular Contributor
  • *
  • Posts: 82
  • Country: gb
Re: Reading firmware out of a mask ROM microcontroller
« Reply #52 on: April 17, 2021, 12:08:47 pm »
Wow, cool!

Interesting it has bootloader 1.00 and the user ID is FF.

By the way, are you able to dump the data ROM and program ROM 2 (ROM they mean flash)?

On your chip there are 3 separate flash areas:
00E000h to 00FFFFh - Internal data ROM (8KB flash area)
010000h to 013FFFh - Internal program ROM 2 (16KB flash area)
0E0000h to 0FFFFFh - Internal program ROM 1 (128KB flash area)

Strange, when you open the .hws file did you get a debug settings dialog?

See in my screenshot, once the project is opened, on the left hand side you can double-click the "boot area mot - 00000000" (hex .mot file) item, and it should disassemble the code.
« Last Edit: April 17, 2021, 12:11:00 pm by tru »
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #53 on: April 18, 2021, 10:16:23 pm »
Wow, cool!

Interesting it has bootloader 1.00 and the user ID is FF.

By the way, are you able to dump the data ROM and program ROM 2 (ROM they mean flash)?

On your chip there are 3 separate flash areas:
00E000h to 00FFFFh - Internal data ROM (8KB flash area)
010000h to 013FFFh - Internal program ROM 2 (16KB flash area)
0E0000h to 0FFFFFh - Internal program ROM 1 (128KB flash area)

Strange, when you open the .hws file did you get a debug settings dialog?

See in my screenshot, once the project is opened, on the left hand side you can double-click the "boot area mot - 00000000" (hex .mot file) item, and it should disassemble the code.

Ah, I found the problem.  When I opened your project, the file path for the bootloader hex file was still set to reference the file using the file paths from your computer.  Once I found the right settings page I was able to point it to the file and then disassemble it.  I then pointed it to my file, selected the correct MCU and was able to disassemble it.

Exporting the disassembly to a text file was a pain with the 10000 line limit and it ended up taking 14 partial files to get it completely exported.

I tried dumping the program ROM2 and the data ROM but the German flash tool just said invalid data range.  Is there somewhere in your program where I can edit what addresses get dumped?
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline tru

  • Regular Contributor
  • *
  • Posts: 82
  • Country: gb
Re: Reading firmware out of a mask ROM microcontroller
« Reply #54 on: April 19, 2021, 03:27:34 pm »
My tool is command line only - the easiest way is to make 3 copies of a sample batch file, e.g.: copy the read flash block A.cmd

Open each in Notepad and replace the line with one of:
Code: [Select]
m16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x00E000 /to_addr=0x00FFFF /file=data-rom.bin
m16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x010000 /to_addr=0x013FFF /file=program-rom2.bin
m16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x0E0000 /to_addr=0x0FFFFF /file=program-rom1.bin

*replace /com=4 with the com port number of the USB/UART

The output is unfortunately in .bin (binary format).  I was too lazy to code the .mot file format.  If I have some spare time, I will add in that feature in.
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #55 on: April 19, 2021, 11:00:14 pm »
My tool is command line only - the easiest way is to make 3 copies of a sample batch file, e.g.: copy the read flash block A.cmd

Open each in Notepad and replace the line with one of:
Code: [Select]
m16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x00E000 /to_addr=0x00FFFF /file=data-rom.bin
m16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x010000 /to_addr=0x013FFF /file=program-rom2.bin
m16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x0E0000 /to_addr=0x0FFFFF /file=program-rom1.bin

*replace /com=4 with the com port number of the USB/UART

The output is unfortunately in .bin (binary format).  I was too lazy to code the .mot file format.  If I have some spare time, I will add in that feature in.

Awesome!  I was able to read out the main program ROM using your tool and I compared it to the bin file I dumped using the German tool and the files were identical.

I then read the program ROM2 and the data ROM but the resulting files were just FF.  They must not be using these memory areas.

I have been looking through the disassembly to find the part that gives the LED flash error code.  When the TV is plugged in, the power LEDs flash in a long, short, long, short pattern.  The power LEDs are connected to P8_0 (pin 20) of the MCU.  I found a subroutine at FE376 that looks to toggle that pin.  The subroutine also has no exit so if the subroutine was ever entered, it would run forever.  The subroutine also toggles P9_6 and P9_7.  I took a look at those pins on the scope and P9_6 is toggling but P9_7 is stuck high.  Both pins have been previously set as outputs so I would expect both to be toggling.

I've attached the disassembled code including some comments I've made.  I have found a few mistakes that I've made after looking trough it a few times and I wouldn't be surprised if there was more.

I'm wondering if there's anything stopping me from making a small modification to the ROM and reflashing the MCU to see if the processor is ending up where I think it is.  Something like changing the code in that subroutine to keep the LED on instead of toggling it.  Then if the LED stayed on I would know that is the subroutine that I am interested in.  Or is there some problem with this that I am not thinking of?
« Last Edit: April 20, 2021, 05:10:23 am by canadaboy25 »
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #56 on: April 20, 2021, 05:08:23 am »
After mapping out the flow of the endless subroutine I found, it seems to continually flash the LEDs at a constant pulse width.  I calculated the number of processor cycles that one pulse would take and compared that to the actual lengths of the slow and fast flashes of the LED on my TV.  If the pulses correspond to a "short" pulse, then the MCU must be running at about 21MHz.  This seems reasonable and the (very sparse) service manual for the TV confirms that a continuous short flashing pattern is an error code for a failed firmware update.  So this must not be the correct subroutine.

I searched the code for other places that bit 0 in the Port 8 register was referenced and found two small subroutines at FF862 and FF874.  These subroutines turn the LEDs on or off and are called from a couple nested subroutines that originate from an interrupt handler at FF554.  I assume this is an interrupt handler since the REIT instruction is called at the end.  However, I cannot figure out what interrupt would be calling it.  I mapped out all the interrupts from the relocatable interrupt vector table but none of them corresponded to this interrupt handler.  I can't find any references to FF554 in any other part of the code so I have no idea what would be calling it.

I thought possibly the code was being copied to RAM and executed from there but that does not make sense as there are jump instructions in the interrupt handler that reference absolute memory locations in the flash memory.

Any ideas where this interrupt handler could be getting called from?

I've updated the assembly code in my last post with my most recent comments.
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 514
  • Country: ru
Re: Reading firmware out of a mask ROM microcontroller
« Reply #57 on: April 20, 2021, 10:02:50 am »
Your guess is correct, those two subs at FFxxx are executed from RAM. The code at FE336+ copies 57F words from FF000 to A08 then jumps there. That A08 code looks like a firmware updater - it talks over UART6 and calls functions manipulating FMRx regs (toggling p9_6 all the way).

BTW, something is wrong with your .asm file. I've tried to convert it back to bin (by extracting addr/data from first two columns) and found 3 gaps: 3 bytes at E752F, 1 byte at E9C40, 2 bytes at EEA60. Looks like your disassembler silently drops bytes it doesn't understand. I've filled the gaps with NOPs and loaded the bin into IDA Pro finally.
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #58 on: April 20, 2021, 10:44:16 am »
Your guess is correct, those two subs at FFxxx are executed from RAM. The code at FE336+ copies 57F words from FF000 to A08 then jumps there. That A08 code looks like a firmware updater - it talks over UART6 and calls functions manipulating FMRx regs (toggling p9_6 all the way).

BTW, something is wrong with your .asm file. I've tried to convert it back to bin (by extracting addr/data from first two columns) and found 3 gaps: 3 bytes at E752F, 1 byte at E9C40, 2 bytes at EEA60. Looks like your disassembler silently drops bytes it doesn't understand. I've filled the gaps with NOPs and loaded the bin into IDA Pro finally.

Sorry, I have attached the raw .bin file.  I should've included it before.

That is interesting, I will take a closer look at it.  I too have switched over to IDA Pro and have gotten a bit further.  So far in IDA the only references to the LED I/O pin are two port initialization functions and that infinite subroutine I found.  I will try looking at the copy in RAM that you described.

The missing addresses may be errors from when I merged all the disassembly files but I was pretty careful to get the indexes correct.  It seems the HEW disassembler treats everything as instructions because viewing the bin file in a hex editor I am able to see a large string pool that HEW tried to interpret as instructions.  IDA also finds some large jump tables.

I am hoping to find the function that does the long-short blink pattern or a general purpose function that blinks the LED in a certain pattern as required.  Attached is the segment from the service manual showing all of the different blink patterns.
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #59 on: April 20, 2021, 11:05:57 am »
Since the Reset vector at the end of the firmware points to FE000, the program should start from there.  It sets up a few system things like stack and interrupt pointers and then goes to the subroutine at FE05C.  Double clicking on "sub_FE05C" at FE054 gets me to the graph view.

The subroutine seems to do two quick checks on the firmware image and if there is an error, enters an infinite loop.  Otherwise, it does 3 more checks that should all pass and does an indirect jump to subroutine at E0102 which I assume is the main program.  Otherwise it follows the tree down and that code at FE336+ you mentioned is at the bottom of the tree.

The 3 checks are all simply copying a value from the flash to RAM and then checking it against a known value which should never fail in normal operation.  I'm guessing these checks will fail when the MCU is started in "bootloader" mode which is really just microprocessor mode then switches the mode back to MCU mode.

So I should never be getting to the bootloader or firmware updater in normal operation, or have I misunderstood how these checks work?
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 514
  • Country: ru
Re: Reading firmware out of a mask ROM microcontroller
« Reply #60 on: April 20, 2021, 01:48:26 pm »
Yes, that RAM code shouldn't be executed in your case (one of the first things it does is erasing a sector at E0000, you'd see it blank if it does). So your blinking must be coming from the "app" code (E0000-EFFFF). But are you sure that LED is on P8_0? Some things don't match: you've mentioned pin 20 but it is P8_1, your manual screenshot shows P8_0 as CECoUT.
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #61 on: April 20, 2021, 03:05:53 pm »
Yes, that RAM code shouldn't be executed in your case (one of the first things it does is erasing a sector at E0000, you'd see it blank if it does). So your blinking must be coming from the "app" code (E0000-EFFFF). But are you sure that LED is on P8_0? Some things don't match: you've mentioned pin 20 but it is P8_1, your manual screenshot shows P8_0 as CECoUT.

Yes, I am very sure that it is on pin 20, at least by the second diagram in the M16C/64A Hardware manual.  The first diagram is for a rectangular version of the M16C/64A and the second diagram is for the square version which I have.  On the square version which I have attached pin 20 is P8_0.  I know for a fact that the LEDs are connected to pin 20 as I can see the trace running to a transistor and then to the LEDs using continuity test.  I have also tested pin 20 with the scope while running and verified that it is in fact an active-high output for the LEDs.

If you are referencing the screenshot from the first page of the thread where pin 20 is P8_1, that is for a completely different MCU that tru has been helping me try to get the firmware out of and it does in fact have P8_1 on pin 20.

tru, was the bootloader that you extracted from the main program ROM1 or from one of the other two flash areas?  Because in the bin file you posted it clearly has VER.4.04 at the beginning of the file.  You mention you get that string as a response when issuing the "get version" command from the bootloader.  Since I get "VER.1.00" as a response I would expect to see that string somewhere in my bin file but I do not.  Of course it may not be stored as a plain string but it seems strange that it wouldn't be.  Does it seem odd that my other two memory areas are all FF, or is that normal?
« Last Edit: April 20, 2021, 03:40:56 pm by canadaboy25 »
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline tru

  • Regular Contributor
  • *
  • Posts: 82
  • Country: gb
Re: Reading firmware out of a mask ROM microcontroller
« Reply #62 on: April 20, 2021, 03:49:29 pm »
Cool, IDA Pro is perfect for this.  The free version only provides Intel disassembly, assuming both of you using free version can I know where to get M16C module/driver from?

The bootloader code I worked on is the Renesas internal bootloader (stored in a separate hidden area).  It is extracted with a different command, my tool using this script hopefully should be able to extract it:
"read bootarea.cmd"

*you will need to open in Notepad and change the com port and the user ID

The hidden area uses the same addressing as the main program ROM: 0x0FF000 0x0FFFFF.  When the debug header is plugged in it pulls some PINs, getting the MCU to switch those addresses to access the hidden area instead of the main program ROM.

Note, though this bootloader isn't part of the TV firmware.  Under normal operation, I don't think the TV runs the Renesas internal bootloader.  It is really for the serial programming debug header, when it is plugged in the Renesas bootloader runs instead of the TV firmware.

What you've already extracted (Program ROM1) is the whole TV firmware, that is assuming program ROM2 is unused - I think is the case as you mentioned it is all FFs.
« Last Edit: April 20, 2021, 03:55:49 pm by tru »
 

Offline tru

  • Regular Contributor
  • *
  • Posts: 82
  • Country: gb
Re: Reading firmware out of a mask ROM microcontroller
« Reply #63 on: April 20, 2021, 04:19:14 pm »
I'm wondering if there's anything stopping me from making a small modification to the ROM and reflashing the MCU to see if the processor is ending up where I think it is.  Something like changing the code in that subroutine to keep the LED on instead of toggling it.  Then if the LED stayed on I would know that is the subroutine that I am interested in.  Or is there some problem with this that I am not thinking of?
There isn't anything special for flashing, except for erasing - the flash erase command can only erase entire blocks, i.e. you cannot erase single bytes of your choosing.  In the hardware manual there is a diagram which displays the blocks (numbers):
Hardware manual: https://www.renesas.com/eu/en/document/man/m16c64a-group-users-manual-hardware?language=en
page 705, Figure 30.4 Program Starting Address in User Boot Mode

Perhaps what might get in the way is the TV firmware code, checking the integrity of the firmware and whether it covers the parts you want to modify, but from your discoveries it looks like only a few bytes here and there is checked.
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 514
  • Country: ru
Re: Reading firmware out of a mask ROM microcontroller
« Reply #64 on: April 20, 2021, 06:05:33 pm »
The "main" code (E0000-EFFFF) accesses all GPIOs in a centralized fashion using package pin numbers translated to IO block:pin using a table at EED9E (bits 7-4 are IO block, 3-0 are pin). The P8_0 is 20th in that table as expected, the function at ECE20 is gpio_read(R1L=pin_idx), the function at ECDCA is gpio_write(R1L=pin_idx, arg_0=value), but there are no calls to these functions passing pin 20! (I'm pretty sure, checked all refs to P8 reg, to gpio_control func, searched for MOV.B #14h, R1L opcode - nothing).
So the only code that manipulates this pin is "bootloader" (F0000+).
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #65 on: April 20, 2021, 10:46:36 pm »
Cool, IDA Pro is perfect for this.  The free version only provides Intel disassembly, assuming both of you using free version can I know where to get M16C module/driver from?

Unfortunately I'm running the pro version so I'm not sure where or if a plugin is available.  I had a look through the program files and it doesn't seem to be as simple as a folder full of the different instruction sets it supports.

The bootloader code I worked on is the Renesas internal bootloader (stored in a separate hidden area).  It is extracted with a different command, my tool using this script hopefully should be able to extract it:
"read bootarea.cmd"

*you will need to open in Notepad and change the com port and the user ID

The hidden area uses the same addressing as the main program ROM: 0x0FF000 0x0FFFFF.  When the debug header is plugged in it pulls some PINs, getting the MCU to switch those addresses to access the hidden area instead of the main program ROM.

Note, though this bootloader isn't part of the TV firmware.  Under normal operation, I don't think the TV runs the Renesas internal bootloader.  It is really for the serial programming debug header, when it is plugged in the Renesas bootloader runs instead of the TV firmware.

What you've already extracted (Program ROM1) is the whole TV firmware, that is assuming program ROM2 is unused - I think is the case as you mentioned it is all FFs.

That's interesting, I had no idea they hid it like that.  I'm not sure if I would've figured that out.  I'll have a go at dumping the bootloader from my chip just to have a look at it.  Really impressive that your program can do all that!

There isn't anything special for flashing, except for erasing - the flash erase command can only erase entire blocks, i.e. you cannot erase single bytes of your choosing.  In the hardware manual there is a diagram which displays the blocks (numbers):
Hardware manual: https://www.renesas.com/eu/en/document/man/m16c64a-group-users-manual-hardware?language=en
page 705, Figure 30.4 Program Starting Address in User Boot Mode

Perhaps what might get in the way is the TV firmware code, checking the integrity of the firmware and whether it covers the parts you want to modify, but from your discoveries it looks like only a few bytes here and there is checked.

Good to know.  If it comes down to it I suppose the worst that will happen is it fails some check and halts the program, in that case I can just reflash the original.

The "main" code (E0000-EFFFF) accesses all GPIOs in a centralized fashion using package pin numbers translated to IO block:pin using a table at EED9E (bits 7-4 are IO block, 3-0 are pin). The P8_0 is 20th in that table as expected, the function at ECE20 is gpio_read(R1L=pin_idx), the function at ECDCA is gpio_write(R1L=pin_idx, arg_0=value), but there are no calls to these functions passing pin 20! (I'm pretty sure, checked all refs to P8 reg, to gpio_control func, searched for MOV.B #14h, R1L opcode - nothing).
So the only code that manipulates this pin is "bootloader" (F0000+).

To make sure I wasn't making a mistake, I checked every pin with the scope to see if any other pins are active.  Only 4 pins were active (other than the two crystal oscillator pins obviously).  P9_6 (pin 99) is toggling at a constant rate and pins 45 and 46 are also toggling but are not correlated to the rate that the LEDs are flashing.  Pin 20 is obviously the pin that is controlling the LEDs.


However, I took a closer look at the waveform for pin 20 and I can see that it is pulsing very quickly while high.  It looks like a PWM signal at 99% duty cycle while high.  This made me think it was being controlled by a hardware timer or PWM function.  Looking back at the pinout of the chip, pin 20 is not only P8_0, but also TA4OUT.  I had a quick look in IDA and there are multiple references to the timer 4 control registers throughout the code.  It makes sense that they would be using a hardware timer as a PWM drive since the snippet from the service manual shows that the LED can be made to "pulsate" with gradual intensity changes.  It would also make sense why we couldn't find the right references to P8_0 since the pin seems to be driven by a timer instead.

I will look into the code manipulating the Timer A4 registers to see if I can confirm my thoughts.
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 514
  • Country: ru
Re: Reading firmware out of a mask ROM microcontroller
« Reply #66 on: April 21, 2021, 11:14:01 am »
You were right, it is TA4, the func at ED354 controls LED PWM duty cycle (R1L=0-100%), func at E844A blinks error code patterns defined by table at EE324. Pattern is selected by vars at D48, D49 set by a func at E8560, which is called from a func at E79E6, which is something like SetErrorCode(R1L=code). For example see E086A:
SetErrorCode(0x16);
DbgPrintf(9, "[EVM]Lamp error over 5 times -> ERR_STBY");

Tracking the 0x16 error code transformation to a bit pattern gets us to a 0x80000000 bit mask - a single blink, which matches your error table from manual. What pattern do you see on your TV?

Upd: the func at E8560 is like SetLEDPattern(R1L=n_slow_pulses, arg_0=n_fast_pulses)

One more idea: you can try acquiring a RAM dump of your error state. Turn on the TV normally (with CNVSS at "normal" level), let it enter error loop, switch CNVSS to BootROM mode, pulse RESET pin of the MCU to go to BootROM, read out the RAM region (0x400-0x33FF).
Actual values of variables and last addresses in stack area could hint something.
« Last Edit: April 21, 2021, 11:43:51 am by abyrvalg »
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #67 on: April 22, 2021, 06:10:56 pm »
You were right, it is TA4, the func at ED354 controls LED PWM duty cycle (R1L=0-100%), func at E844A blinks error code patterns defined by table at EE324. Pattern is selected by vars at D48, D49 set by a func at E8560, which is called from a func at E79E6, which is something like SetErrorCode(R1L=code). For example see E086A:
SetErrorCode(0x16);
DbgPrintf(9, "[EVM]Lamp error over 5 times -> ERR_STBY");

Tracking the 0x16 error code transformation to a bit pattern gets us to a 0x80000000 bit mask - a single blink, which matches your error table from manual. What pattern do you see on your TV?

Upd: the func at E8560 is like SetLEDPattern(R1L=n_slow_pulses, arg_0=n_fast_pulses)

One more idea: you can try acquiring a RAM dump of your error state. Turn on the TV normally (with CNVSS at "normal" level), let it enter error loop, switch CNVSS to BootROM mode, pulse RESET pin of the MCU to go to BootROM, read out the RAM region (0x400-0x33FF).
Actual values of variables and last addresses in stack area could hint something.

Very interesting discoveries!  You are much quicker at finding the relevant functions than I am.  It is tricky to follow the program flow once everything starts getting referenced from RAM.

When plugging in the TV, it flashes the fast-slow-fast-slow pattern from the first row in the service manual snippet I posted.

Another interesting note, while originally troubleshooting the TV I did some research and found that other similar Sharp TVs could be forced to power up and ignore backlight errors by holding a combination of the menu buttons while plugging the TV in.  I tried every combination of buttons listed online but never was able to get it to power up in this special mode.  I assumed it was because this TV uses capacitive touch sensors as the buttons instead of physical switches.  However, one of the text strings at 0E96E says "[EVM]Specail start: No Error" (funny how they misspelled "special" in all the messages).  Searching for references to "E96E" in IDA gives a branch at E0E61 which sets byte_D21 that is checked in the set_error_code function to 5 which means no error.  So it seems the functionality is in fact there, but it is so far down many different branches that I am having trouble finding what conditions actually have to be met to enter this mode.

On the note of trying to get a RAM dump, I think the bootloader that tru posted ended up copying itself into RAM and executing itself from there which would defeat the purpose of trying to get a memory dump.  Perhaps it would leave enough of the memory unaffected.  I tried extracting the bootloader from my chip to see if this was the case but I couldn't get it to work.  I used the read_bootarea tool with updated COM port and user ID and it verified the ID successfully but timed out trying to read the first chunk of data.  I was still able to issue the get version command after the failed attempts so the MCU wasn't locked up, it just wasn't responding to that command.  Any ideas what I am doing wrong with the tool?
« Last Edit: April 22, 2021, 06:14:14 pm by canadaboy25 »
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #68 on: April 22, 2021, 09:16:12 pm »
I attempted the RAM dump anyways without much result.  I first tried dumping the ram after starting the TV in bootloader mode and the resulting file was all FF.  I then powered on the TV normally and switched the CNVSS high, pulsed the reset line, and dumped the RAM again.  Still all FF.  It seems strange to me that I'm getting all FF for the program ROM2, data flash, RAM, and also can't dump the bootloader.  I know tru's tool is set up correctly and working since I can dump the main firmware with it.  Perhaps the bootloader version 1.00 doesn't support these other areas?
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline tru

  • Regular Contributor
  • *
  • Posts: 82
  • Country: gb
Re: Reading firmware out of a mask ROM microcontroller
« Reply #69 on: April 22, 2021, 11:14:32 pm »
On the note of trying to get a RAM dump, I think the bootloader that tru posted ended up copying itself into RAM and executing itself from there which would defeat the purpose of trying to get a memory dump.  Perhaps it would leave enough of the memory unaffected.  I tried extracting the bootloader from my chip to see if this was the case but I couldn't get it to work.  I used the read_bootarea tool with updated COM port and user ID and it verified the ID successfully but timed out trying to read the first chunk of data.  I was still able to issue the get version command after the failed attempts so the MCU wasn't locked up, it just wasn't responding to that command.  Any ideas what I am doing wrong with the tool?
I've looked into the hardware manual again, the boot loader software commands for single chip boot mode is not listed in your model.  In the manual of the M30624FGPGP it lists all software commands for single chip mode.  Perhaps being v1.00 it doesn't include such read boot area code command.
« Last Edit: April 22, 2021, 11:28:01 pm by tru »
 

Offline tru

  • Regular Contributor
  • *
  • Posts: 82
  • Country: gb
Re: Reading firmware out of a mask ROM microcontroller
« Reply #70 on: April 22, 2021, 11:19:03 pm »
In page 712 of your hardware manual:

There is table of boot loader software commands for Rewrite mode (different mode from single chip mode):
Table 30.15 Software Commands:
Code: [Select]
Read array Write
Read status register Write
Clear status register Write
Program Write
Block erase Write
Lock bit program Write
Read lock bit status Write
Block blank check

However, I think that isn't the complete list because the read version command is not listed there.
« Last Edit: April 22, 2021, 11:41:36 pm by tru »
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 514
  • Country: ru
Re: Reading firmware out of a mask ROM microcontroller
« Reply #71 on: April 23, 2021, 11:14:20 am »
That "special mode: no error" is entered by holding some 3 touch keys pressed (0x49 bitmask of pressed keys). Possible masks/modes:
45 - special: inspection
29 - special: hotel (public)
25 - special: hotel2 (public2)
49 - special: no error
15 - special: calibration
09 - special: version up

Looks like the "version up" is firmware upgrade mode, so if you know a 2-key combination to enter it - just try it with all possible 3rd keys.
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #72 on: April 23, 2021, 11:36:21 am »
I've looked into the hardware manual again, the boot loader software commands for single chip boot mode is not listed in your model.  In the manual of the M30624FGPGP it lists all software commands for single chip mode.  Perhaps being v1.00 it doesn't include such read boot area code command.

In page 712 of your hardware manual:

There is table of boot loader software commands for Rewrite mode (different mode from single chip mode):
Table 30.15 Software Commands:
Code: [Select]
Read array Write
Read status register Write
Clear status register Write
Program Write
Block erase Write
Lock bit program Write
Read lock bit status Write
Block blank check

However, I think that isn't the complete list because the read version command is not listed there.

Hmm, that's interesting.  The hardware manual for the flash version of the other Renesas MCU we were working on has the same incomplete table.  However, it describes the possibility of rewriting the bootloader while the hardware manual for the 16C/64A doesn't seem to.  Perhaps they disabled this and that's why it is still Ver 1.00?  Either way it's probably close enough to the version you were able to dump to have an idea of how it works.

That "special mode: no error" is entered by holding some 3 touch keys pressed (0x49 bitmask of pressed keys). Possible masks/modes:
45 - special: inspection
29 - special: hotel (public)
25 - special: hotel2 (public2)
49 - special: no error
15 - special: calibration
09 - special: version up

Looks like the "version up" is firmware upgrade mode, so if you know a 2-key combination to enter it - just try it with all possible 3rd keys.

Wow, nice!  I'm not sure what the combination for the firmware upgrade is either.  Very sparce information on this TV.  Either way, there are only about 6 keys.  Won't take long to try all combinations.  I was previously just trying 2-key combinations.  I'll give it a shot and see if anything happens.


I got sidetracked in IDA looking through the function at E5F4E which is an EEPROM integrity check function.  The external EEPROM is connected via the UART2 interface in I2C mode.  Throughout this function values are being copied to the RAM from the EEPROM.  I took a quick look at the lines with the scope and there is in fact a good chunk of data being transferred on power-up.  Makes it even trickier to trace the exact place that I am failing this backlight check in the code.  Perhaps it would be easier to try modding the firmware to dump RAM values out an unused UART interface.  It wouldn't take long to try modifying some values in the large unused space in the firmware to see if I trip some type of checksum.  Let me know what you think about this.
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 

Offline tru

  • Regular Contributor
  • *
  • Posts: 82
  • Country: gb
Re: Reading firmware out of a mask ROM microcontroller
« Reply #73 on: April 23, 2021, 02:52:21 pm »
I forgot to mention that there is another special software command, I think is for debugging purposes, it downloads code to RAM (from 0x600), does integrity check then jumps to your code which executes it.  It works on the VER.4.04 boot loader.

I've included a HEW project with the sample code that sets port P8_0 to high for you.
It also contains the required code to pass the boot loader integrity check.

If it works on VER.1.00 you should see the LED constantly lit.

I've added 3 files to:
https://github.com/truhy/m16c-flasher/tree/main/Sourcecode/Release

"boot_dl_P8_0 source code - HEW project.zip" = source code of below
"boot_dl_p8_0.bin" = program to be uploaded into RAM
"upload to ram - p8_0.cmd"

The files are prepared and ready to go, simply edit the batch file "upload to ram - p8_0.cmd" with your COM port and try.

If you want to modify and recompile the test code:
Note, as you've found out already, since HEW was made in the past the workspace and project files (plain text files) stores absolute paths and needs correcting (find and replace).
There is another small problem, unfortunately my tool supports only input binary file so I have included srec_cat with a batch file to convert motorola into binary, but it also fills in zeroes before 0x600 so you will need to remove them.
« Last Edit: April 23, 2021, 02:54:53 pm by tru »
 

Offline canadaboy25

  • Regular Contributor
  • *
  • Posts: 112
  • Country: ca
Re: Reading firmware out of a mask ROM microcontroller
« Reply #74 on: April 23, 2021, 08:09:26 pm »
I tried holding down every combination of 3 buttons while plugging in the TV and nothing changed.  I'm not sure if it is even reading the buttons or not.  Really hard to tell with the capacative touch buttons.

I forgot to mention that there is another special software command, I think is for debugging purposes, it downloads code to RAM (from 0x600), does integrity check then jumps to your code which executes it.  It works on the VER.4.04 boot loader.

I've included a HEW project with the sample code that sets port P8_0 to high for you.
It also contains the required code to pass the boot loader integrity check.

If it works on VER.1.00 you should see the LED constantly lit.

I've added 3 files to:
https://github.com/truhy/m16c-flasher/tree/main/Sourcecode/Release

"boot_dl_P8_0 source code - HEW project.zip" = source code of below
"boot_dl_p8_0.bin" = program to be uploaded into RAM
"upload to ram - p8_0.cmd"

The files are prepared and ready to go, simply edit the batch file "upload to ram - p8_0.cmd" with your COM port and try.

If you want to modify and recompile the test code:
Note, as you've found out already, since HEW was made in the past the workspace and project files (plain text files) stores absolute paths and needs correcting (find and replace).
There is another small problem, unfortunately my tool supports only input binary file so I have included srec_cat with a batch file to convert motorola into binary, but it also fills in zeroes before 0x600 so you will need to remove them.

Cool!  I gave your sample script a try and it worked perfectly.  LED was lit up solid.  I wonder if it is possible to switch over to this special command mode without losing the values stored in the RAM.  If so, I would theoretically be able to set up the UART interface in code and dump out the rest of the RAM that hasn't been overwritten.  I'll give getting a UART set up a try to see if I can at least get it printing data.
canadaboy25

- Sometimes the light at the end of a tunnel is an on-coming train
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf