I've still been unable to successfully load the H7F Flash drivers into the MPC5566's RAM and execute them with the intention of using the drivers to load a new program into the MPC5566's Flash. I'm using an ATmega64M1 to interface with the MPC5566 through the JTAG. To date, I've been able to:
1. Initialize the JTAG TAP controller.
2. Enable the OnCE.
3. Enter external debug mode.
4. Read and write the OSR, CPUSCR, GPRs, SPRs, and the internal SRAM in both single and burst modes.
5. Exit debug mode.
It seems I have the main pieces tested and ready to start exercising the Flash drivers, but here's where I'm having trouble.
1. When I write the MAS0-3 registers and execute the tlbwe instruction to set up the addresses (as in Table 9 of the AN3283 for non-VLE Flash drivers running in internal SRAM), the write appears to work properly, but when I read the MMU back, the value that was set in MAS3 is now in MAS0, MAS1, MAS2, and MAS3.
2. When I attempt to initialize the SRAM, the initialization takes several minutes. My routine sets the SRAM beginning address to 0x40000000 and the SRAM size to 0x1FFFF / 0x80. It then loops through SRAM size times, and does the following:
a. registerVal = sramBegin + (i * 0x80);
b. writes CPUSCR->WBBRlo with the registerVal, and CPUSCR->IR with the stmw instruction.
c. Single Steps through the stmw instruction.
3. When I set up the FMPLL, I'm not sure that I have the correct values because my program never returns from the function, but here is the process:
a. Save the FMPLL_SYNC register address to GPR3.
b. Save the new value to be written to FMPLL_SYNC to GPR4. The value is (MSB first) = 0b 0000 0000 0000 0000 0000 1001 0000 0000, which should set the Fref to 8 MHz crystal, PREDIV to 0b000 (divide by 1, default), MFD = 0b10000 (16), RFD = 0b001 (2), Fsys = 8 * (20 / 2^2) = 40 MHz.
c. Execute the lwarx instruction, where GPR3 contains the address of word to be loaded and replaced. The word is temporarily stored in GPR5 while a reservation of the memory location in GPR3 is created.
d. Execute the stwcx instruction, which stores the contents of GPR4 into the reserved memory at GPR3.
e. Execute msync between the write to FMPLL_SYNC[MFD] and the read of FMPLL_SYNSR[LOCK]
f. Read the data at FMPLL_SYNSR to GPR5 and poll the FMPLL_SYNSR[LOCK] bit to see when it is set. My program hangs here.
Any help with these issues would be greatly appreciated. Thank you in advance!
1. To be able to read back the TLB settings, it's necessary to specify number of TLB to read in MAS0[ESEL] bit field and then execute tlbre instruction. Are you following these steps?
2. Because it's necessary to execute 1024 iterations, it makes sense to initialize only small piece of RAM in this way and then load short code to this area which will initialize the rest of RAM. This should be faster option.
Here is an initialization code from CodeWarrior project:
Just compile this piece of code (it needs to be updated as mentioned above because piece of RAM will be initialized via JTAG), load it to RAM, add bkpt instruction at the end and execute in the same way as SSD functions as described in AN3283. bkpt instruction will force the device back to debug mode.
3. You can use this excel tool to generate the numbers and to see the right sequence.
I appreciate the thorough response. The suggestion for speeding up clearing the memory was great, and I made some modifications to my register values for setting the FMPLL based on your spreadsheet calculator.
I'm still having trouble with the tlbre instruction. First, I set MAS0[ESEL] to read Peripheral Bridge B (0x1000 0000) and put it in SPR 624. Next I execute tlbre, then I read the contents of SPR 624, 625, 626, and 627, which I understand should now have the contents of MAS0 - MAS3. I read back MAS0 = 0x1000 0000, MAS1 = 0x1000 0000, MAS2 = 1000 0000, MAS3 = 1000 0000.
Next, I set MAS0[ESEL] to read the Internal SRAM (0x1001 0000). The result after the tlbre and reading SPR 624-627 is MAS0 = MAS1 = MAS2 = MAS3 = 0x1001 0000.
I then set MAS0[ESEL] to read Peripheral Bridge A (0x1002 0000). The result after the tlbre and reading SPR 624-627 is MAS0 = MAS1 = MAS2 = MAS3 = 0x1002 0000.
Finally, I set MAS0[ESEL] to read Internal Flash (0x1003 0000). The result after the tlbre and reading SPR 624-627 is MAS0 = MAS1 = MAS2 = MAS3 = 0x1003 0000.
I was under the impression that executing the tlbre instruction would load the MAS0-3 into the SPRs all at once. Is this not the case?
your procedure is correct, I can see nothing wrong. No other steps are needed.
I was searching for some sample code and I found this one in my repository:
asm void MMUEBIIsCacheInhibited(void)
lis r3, 0x1002 /* Select TLB entry #, define R/W replacment control */
mtMAS0 r3 /* Load MAS0 with 0x1002 0000 for TLB entry #2 */
tlbre /* Get TLB entry # information */
mfspr r3, MAS2
ori r3, r3, 0x0008 /* set I bit (Page is cache inhibited) */
/* make sure RPN is 0x20000000 */
oris r3, r3, 0x2000
msync /* make sure we finished all memory accesses */
tlbwe /* Write entry defined in MAS0 (entry 2 here) to MMU TLB */
isync /* Wait for tlbwe to complete, then flush instruction buffer */
This one was used to modify certain TLB entry. So, it just reads out TLB entry using tlbre, modifies it and writes back using tlbwe. It's very simple code and it shows that it is sufficient to write to MAS0 register and execute tlbre.
The only idea I have is that there's some SW issue in your code because this should really work.