Mac OS 9 Lives

Classic Mac OS Software => Application Development & Programming => Topic started by: joevt on November 22, 2022, 10:24:25 AM

Title: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: joevt on November 22, 2022, 10:24:25 AM
Gestalt doesn't return the correct CPU type for my G4 upgraded Power Mac 8600 in Mac OS 9. Is there another way to get the CPU type?

The pvr (processor version register) is a special purpose register that has the needed info. The following code in CodeWarrior .cpp file should be able to get the value:
Code: [Select]
register UInt32 pvrval;
asm { mfpvr pvrval };
but it causes a privileged instruction exception since that register is only available in supervisor mode. Is there a way to enter and exit supervisor mode?

Utilities like Powerlogix CPU Director or XLR8 Mach Speed Control have code to display the pvr. CPU Director seems to use a PowerPC system call but I don't know the details.
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: teroyk on November 22, 2022, 12:50:25 PM
I think you should change Machine Status Register (MSR) first.
Bit 17 in MSR is privilege level (0: user and supervisor-level; 1: user only)
Somebody who know better can continue how to do it nicely.
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: robespierre on November 22, 2022, 10:30:17 PM
The only way to enter supervisor mode is by taking an exception—either an explicit system call (sc) or trap (tw) instruction, or a floating point trap—or servicing an interrupt; both of which redirect execution to system code in the trap or interrupt handler. Changing the MSR (with the mtmsr instruction) is not available from user mode.

The whole reason a processor has a user/supervisor mode bit is to establish limits on what ordinary programs can do. If a program running in user mode could simply change the bit, it could effectively take over the system.

With that said, I wonder when Mac OS began using the user mode. When I did most of my hackery in System 7.5.5, it was in supervisor mode all of the time.
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: Naiw on November 24, 2022, 09:26:49 AM
If I remember correctly there is a ”backdoor” in the 68k emulator that allows you to enter/exit ppc supervisor mode; I don’t remember the details but as far as I remember you loaded some constants like Gary or similar (suppose it’s either designed by or an homage to Gary Davidian who made the first 68k emulator implementation).

Unfortunately I can’t find the example code when I attempt to google.
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: Naiw on November 24, 2022, 02:01:19 PM
After a bit memory juggling I recalled that the old BootX bootloader used this trick (and obviously another as well, the latter I never tested myself- the 68k emulator way I've tested on both PCI and Nubus macs however).

See file EnterPPCSupervisor.c in either of the source packages here.

https://sourceforge.net/projects/nubus-pmac/files/BootX%20boot%20loader/
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: Naiw on November 24, 2022, 02:04:53 PM
With that said, I wonder when Mac OS began using the user mode. When I did most of my hackery in System 7.5.5, it was in supervisor mode all of the time.

Mac OS never been running in supervisor mode on either PPC or 68k, 68k MacOS did however have a toolbox trap that allowed you to enter supervisor mode.
On PPC macos there never was any documented way to enter supervisor mode.
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: Naiw on November 24, 2022, 02:22:06 PM
Gestalt doesn't return the correct CPU type for my G4 upgraded Power Mac 8600 in Mac OS 9. Is there another way to get the CPU type?

The pvr (processor version register) is a special purpose register that has the needed info. The following code in CodeWarrior .cpp file should be able to get the value:
Code: [Select]
register UInt32 pvrval;
asm { mfpvr pvrval };
but it causes a privileged instruction exception since that register is only available in supervisor mode. Is there a way to enter and exit supervisor mode?

Utilities like Powerlogix CPU Director or XLR8 Mach Speed Control have code to display the pvr. CPU Director seems to use a PowerPC system call but I don't know the details.

I might misremember now, but while you can accomplish this for sure in supervisor mode, I believe you could actually read most previledged registers by exploiting the exception handler functionality of the multiprocessing lib, you could only modify a subset of the bits in each register though- I recall playing around with attempting to implement "protected memory" in OS 8/9 by using an exception handler that used the single step bit in the MSR to break arbitrary in software to calculate the EA of upcoming load/store instructions against the application memory bounds for development purposes.

It should be noted tho the callback that you register with InstallExceptionHandler, does not execute in supervisor mode though- you get all registers handed via a structure to the call and that's also how it "filters" what bits you can modify or not.
I could remember incorrectly though... it's about 23 years ago I actually did any classic MacOS development to speak of.

(Multiprocessing lib has a lot of interesting things outside of this btw if you develop "new" macos software, features that clearly wasn't properly understood or overlooked by the vast majority of the developers back then for whatever reason)
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: joevt on November 25, 2022, 10:02:38 PM
I tried installing an exception handler but it didn't seem to get called for the mfspr instruction. And the list of registers doesn't include the processor version register.

What I'm currently doing is getting the processor version value from the Name Rgistry (I/O Registry in Mac OS X). It's the cpu-version property in the cpu device. I'm using it to fix XPostFacto's CPU detection in Mac OS 9 for better boot device warning messages.
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: Naiw on November 29, 2022, 09:24:55 PM
I tried installing an exception handler but it didn't seem to get called for the mfspr instruction. And the list of registers doesn't include the processor version register.

What I'm currently doing is getting the processor version value from the Name Rgistry (I/O Registry in Mac OS X). It's the cpu-version property in the cpu device. I'm using it to fix XPostFacto's CPU detection in Mac OS 9 for better boot device warning messages.

That sounds weird, did it trigger if you did perform an 'sc' for example?

Yes you're right I completely forgot about the name registry, it's of course the clean room solution to do it.
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: joevt on December 01, 2022, 03:29:39 AM
That sounds weird, did it trigger if you did perform an 'sc' for example?
I didn't try sc. Just mfspr.
Anyway, the exception handler documentation says the handler is executed in the same context as when it was installed, so it also wouldn't be able to execute supervisor mode instructions.

I found that in 2004 I did Jasik Nosy on the XLR8 Mach Speed Control Panel. It did some weird stuff that maybe involves the 68K emulator to get into supervisor mode? I don't remember how far I got into looking at that or why I was looking at it - it's been almost a couple decades.  The reason I say 68K emulator is because of some addresses, used in the code, in the 0x68000000 ... 0x69000000 range which I read recently might be related to the 68K emulator which I know very little about.

Here's some incomplete pseudo code. XLR8 Mach Speed Control doesn't include debugger symbols like the PowerLogix CPU Director app does so I had to make up some function names.
Title: Re: Detecting CPU type in OS 9 - Supervisor Mode?
Post by: Naiw on December 01, 2022, 08:41:38 AM
No exactly it wouldn't, but the exception handler gets handed a structure that contains the register values of both user and supervisor registers; that is also how you would modify supervisor level register as they're written back (although filtered) when the exception handler returns, which allows you to set bits such as MSR[SE] to single step.

But the documentation is correct, you can not execute supervisor isa instructions in the exception handler context (as I wrote previously, PowerPC Mac OS always run in usermode and that included exception handling).