Register

TLB operation safety

Discuss anything related to calculators. For specific help on certain games/programs check the Released Projects subforum.
Member
User avatar
Posts: 39
Joined: Fri Aug 21, 2015 11:54 am
Location: France
Calculators: Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860GII, Casio fx-CG50

TLB operation safety

Postby lephe » Wed Jul 20, 2016 10:00 am

Hello Casiopeia :)

I've encountered TLB misses while working with a custom interrupt handler recently. I finally figured out that I had to fill the TLB manually because I replace the TLB miss handler. I don't fully understand how the system handles it yet, because it only initializes a few TLB entries for code and 8k for RAM (which is not enough to cover the whole memory theoretically available to add-ins) at add-in startup, and TLB misses seem usually reported as System ERRORS instead of being handled. Maybe the TLB is usually initialized by the initialization routine call generated by the fx-9860G SDK but I haven't disassembled it yet.

Do you have any clue about how it works ?

More importantly, I have read a few scary things about manually changing MMU or TLB settings (like AHelper bricking a calculator :wtf: ) so I'me basically wondering if it is safe for me to edit the TLB entries. I'm not planning on doing anything complicated like running ELF files, only :

  • Save the TLB entries at startup
  • Load enough TLB data for the add-in to run properly
  • Execute code...
  • Restore TLB entries when leaving the add-in

I found that MMUCR, PTEH, PTEL and TTL are more or less initialized by a manual reset. I know that syscall 0x000 does many MMU initialization, and I believe this kind of initialization is done at startup when still running code in P2 space.

Is it correct to suppose that a manual reset will basically reset the four registers and the TLB contents ?

Finally (I'm almost done, sorry for the long post), it looks like virtual RAM addresses are always translated to the same locations, but not ROM addresses (those who begin with 0x300) where the application code resides. I was planning to « guess » the physical location by reading the default entries set by the system, but there is probably fragmentation in the physical memory.

So, is it possible to compute the location of the add-in code in the physical memory ?

Any help would be greatly appreciated. :D

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: TLB operation safety

Postby SimonLothar » Wed Jul 20, 2016 10:00 pm

For fx9860:
The Addins (residing in ROM) are virtualized to 0x00300000. The fragmentation is heeded for. The fragments are virtualized in the right order, of course.
The 8k RAM is the static RAM. It is virtualized to 0x08100000.
The other RAM areas - heap and stack - are not virtualized.

Concerning the fragmentation:
I found the prizm syscall, which returns the fragments of an addin (http://www.casiopeia.net/forum/viewtopic.php?f=22&t=1738#p14339). I will try to find it on fx9860, too.

An addin cannot set its own TLB-entries. If the addin runs, it already runs virtualized. It would be like assembling a bicycle while driving it.
The TLB is set by the addin-starting procedure inside the OS, before the addin is started.

I'd recommend not to touch the TLB.
I'll be back!

Member
User avatar
Posts: 39
Joined: Fri Aug 21, 2015 11:54 am
Location: France
Calculators: Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860GII, Casio fx-CG50

Re: TLB operation safety

Postby lephe » Wed Jul 20, 2016 10:43 pm

Well, I would expect an add-in to be run virtualized. But what actually happens is that I get TLB misses for addresses which are both in RAM and in the virtual area where the code resides. For instance, I'm just getting a TLB miss for hitting address 0x00301dc4, which is the address of a function in my add-in.

The documentation explains that a TLB miss should be handled by loading the corresponding entry to the TLB (as I would expect). The system may well load everything at startup and only report TLB misses that occur during execution through System ERRORS, but in this case, there are obviously entries missing or some initialization skipped.

By the way, following the original code I found when I got interested into Linux development, I call Hmem_SetMMU(0x08102000, 0x8801e000, 108) at initialization. As far as I understood when I disassembled this syscall (quite a long time ago), it does set TLB entries.

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: TLB operation safety

Postby SimonLothar » Thu Jul 21, 2016 8:37 am

lephe wrote:Well, I would expect an add-in to be run virtualized. But what actually happens is that I get TLB misses for addresses which are both in RAM and in the virtual area where the code resides. For instance, I'm just getting a TLB miss for hitting address 0x00301dc4, which is the address of a function in my add-in.
I just checked it and used the following statements:
result = *((int*)0x00300000);
result = *((int*)0x00300200);
result = *((int*)0x0030ea94);
0x0030ea94 is the last address in the map-file of the addin I used.
I did not encounter any error message on fx9860GII (SH-4);OS2.09, fx9860GII (SH-3);OS2.00, fx9750GII (SH-4);OS2.02, fx9860G slim;OS 2.01.
The results were always the same and plausible.

lephe wrote:By the way, following the original code I found when I got interested into Linux development, I call Hmem_SetMMU(0x08102000, 0x8801e000, 108) at initialization. As far as I understood when I disassembled this syscall (quite a long time ago), it does set TLB entries.
This is correct. I only recommended not to touch the TLB.
I'll be back!

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: TLB operation safety

Postby SimonLothar » Thu Jul 21, 2016 9:12 am

lephe wrote:...but there is probably fragmentation in the physical memory. So, is it possible to compute the location of the add-in code in the physical memory ?
On fx9860 syscall 0011 is the counterpart to syscall 0026 on the prizm. Though, prizm's syscall 1DAA has not been implemented as syscall in the fx9860-OSes. The enumeration of the fragments seems to be embedded in syscall 0011 and seems to use the internal file-information-structure related to the file-handle.
Possibly the structure looks like this (which is used with findfirst/findnext)
typedef struct tag_FILE_INFO
{
unsigned short id;
unsigned short type;
unsigned long filesize;
unsigned long datasize;
unsigned int property;
unsigned long address;
} FILE_INFO;
Looks as if they use a fragment-size of 0x2000 on fx9860-calculators.
I'll be back!

Member
User avatar
Posts: 39
Joined: Fri Aug 21, 2015 11:54 am
Location: France
Calculators: Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860GII, Casio fx-CG50

Re: TLB operation safety

Postby lephe » Thu Jul 21, 2016 2:32 pm

SimonLothar wrote:I just checked it and used the following statements:
result = *((int*)0x00300000);
result = *((int*)0x00300200);
result = *((int*)0x0030ea94);
0x0030ea94 is the last address in the map-file of the addin I used.

I tried the same thing to see what could be done. I used two addresses :
  • 0x00301dcc is the address of the function that causes the TLB miss when called (it moved because I added some code)
  • 0x00304408 is the address of the last symbol of my add-in in the 0x300-section

I had forgotten to say that my TLB miss handler catches my unexpected TLB miss when the function residing at 0x00301dcc is called (which means it's an instruction access rather than a data access : possibly it may matter ?).

So I tried to access 0x00300000, 0x00300200 and 0x00304408 by pointer. Everything worked well, whether this work was done before my interrupt handler was initialized (i.e. when the system still answered TLB misses) or not. But I still had this TLB miss triggered when jumping to 0x00301dcc.

Then I read 0x00301ddc instead (and it was before my interrupt handler was initialized), and the TLB miss just disappeared. Now, if I run the same pointer access with my handler set up, then I get a TLB miss for hitting 0x00301dcc with an spc value which correspond to the pointer access.

Thus I believe that the system updates the TLB during execution. This is why I originally meant to edit the TLB -- to reproduce this behavior.

SimonLothar wrote:This is correct. I only recommended not to touch the TLB.

So, why does this call exist in first place ? I could remove it -- usually it has no visible effect -- but there must be a reason why it's here.

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: TLB operation safety

Postby SimonLothar » Fri Jul 22, 2016 6:02 am

lephe wrote:
SimonLothar wrote:This is correct. I only recommended not to touch the TLB.
So, why does this call exist in first place ? I could remove it -- usually it has no visible effect -- but there must be a reason why it's here.
The syscall is used inside the OS, when virtualizing the addin and the static RAM. The syscalls we know are based on observation, deduction and experimenting. We do not know every aspect of their behavior (side effects, prerequisites). That is the reason, why I'd use TLB-syscalls only in an experimenting context. The problem is that the addin runs virtualized and changing TLB-settings can pull the rug out from under the addin.
I'll be back!

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: TLB operation safety

Postby SimonLothar » Fri Jul 22, 2016 6:23 am

lephe wrote:Thus I believe that the system updates the TLB during execution. This is why I originally meant to edit the TLB -- to reproduce this behavior.
An unexpected TLB-miss can occur, when the addin changes itself (t. i. the G1A/G3A-file) using some Bfile-functions. Or the addin changes TLB-settings. The system changes the TLB-settings when switching tasks in the main menu (possibly only if switching to a different addin). Do you use a persistent interrupt-handler, which could possibly be called after a task-switch?
I'll be back!

Member
User avatar
Posts: 39
Joined: Fri Aug 21, 2015 11:54 am
Location: France
Calculators: Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860GII, Casio fx-CG50

Re: TLB operation safety

Postby lephe » Fri Jul 22, 2016 7:51 am

Apart from the call to Hmem_SetMMU() at initialization, I only access the TLB for reading and for debugging purposes. I was waiting for your answers before changing any setting. I don't use Bfile either -- as for now I'm still focused on basic tasks such as timer management and efficient drawing.

As for my interrupt handler, I properly deinstall it when the add-in ends, restoring every changed register and (finally) the vbr, so I'm sure every job usually handled by the system is still done. It's only meant to be used inside the add-in to add some functionalities, namely CPU timer access for the gray engine.

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: TLB operation safety

Postby SimonLothar » Fri Jul 22, 2016 5:47 pm

lephe wrote:As for my interrupt handler, I properly deinstall it when the add-in ends, restoring every changed register and (finally) the vbr, so I'm sure every job usually handled by the system is still done. It's only meant to be used inside the add-in to add some functionalities, namely CPU timer access for the gray engine.
I suppose you either disable task-switches (MENU-key) or heed for them somehow. Apart from that I am at a loss here.
I'll be back!

Next

Return to General

Who is online

Users browsing this forum: No registered users and 4 guests