Problem with bus clock setting on slim 3.71
Problem with bus clock setting on slim 3.71
Here's some test result(Set bus clock to 50):
Function/Result
scePowerSetClockFrequency(in both scePower and scePower_driver)/Bus clock reset to about 95
scePowerSetBusClockFrequency(in both scePower and scePower_driver)/Bus clock's still 111
sctrlHENSetSpeed/Bus clock reset to about 95
It seems system or M33 driver locked bus clock minimum value to 95?
PS: the sceSysReg series function nids are changed without known alias so that i cannot test them
Function/Result
scePowerSetClockFrequency(in both scePower and scePower_driver)/Bus clock reset to about 95
scePowerSetBusClockFrequency(in both scePower and scePower_driver)/Bus clock's still 111
sctrlHENSetSpeed/Bus clock reset to about 95
It seems system or M33 driver locked bus clock minimum value to 95?
PS: the sceSysReg series function nids are changed without known alias so that i cannot test them
It's worse... with the MediaEngine running, trying to change the clock freezes the Slim. I'm still trying to figure out how to turn the ME off to change the clock. I posted a request for the nid for disabling the clock to the ME, but no response yet. I tried getting the value myself, but I don't know if it was correct.
Anyway, the set clock function also ignores calls with paramters it doesn't like. For example, scePowerSetClockFrequency(333, 333, 167) is ignored completely, while scePowerSetClockFrequency(333, 333, 166) works fine. That's why the clock doesn't change on some homebrew - the values they send are no longer acceptable. One rule I found - round down when dividing by two.
Anyway, the set clock function also ignores calls with paramters it doesn't like. For example, scePowerSetClockFrequency(333, 333, 167) is ignored completely, while scePowerSetClockFrequency(333, 333, 166) works fine. That's why the clock doesn't change on some homebrew - the values they send are no longer acceptable. One rule I found - round down when dividing by two.
Hi! :)
I'm having problems with scePowerSetBusClockFrequency (only in kernel 3.71)
I used the following code to test CPU/BUS combination.
In kernel 3.52 all the combination are valid, but in kernel 3.71 the bus is always at 111.
I thought the values that follows the rule pll>=cpu>=bus*2 should work.
P.S. Another "quick" question. I tried to use sctrlHENSetSpeed in a kernel prx.
I included systemctrl.h and linked pspsystemctrl_kernel, but I get and "undefined reference" error during compilation.
Where's the function sctrlHENSetSpeed? :)
Many thanks.
Ciaooo
Sakya
I'm having problems with scePowerSetBusClockFrequency (only in kernel 3.71)
I used the following code to test CPU/BUS combination.
In kernel 3.52 all the combination are valid, but in kernel 3.71 the bus is always at 111.
I thought the values that follows the rule pll>=cpu>=bus*2 should work.
Code: Select all
int main(){
int cpu, curCpu, resetCpu;
int bus, curBus, resetBus;
int ok = 0;
char text[30];
SceUID logFile;
pspDebugScreenInit();
SetupCallbacks();
pspDebugScreenPrintf("Clock test for 3.71\n\n");
logFile = sceIoOpen("./test.log", PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
if (!logFile){
pspDebugScreenPrintf("Error opening log file!\n");
sceKernelDelayThread(10000);
return -1;
}
resetCpu = 222;
resetBus = 111;
pspDebugScreenPrintf("Testing:\n");
for (cpu=resetCpu; cpu > 10; cpu--){
pspDebugScreenPrintf(".");
for (bus=resetBus; bus > 10; bus--){
scePowerSetClockFrequency(resetCpu, resetCpu, resetBus);
scePowerSetCpuClockFrequency(cpu);
if (scePowerGetCpuClockFrequency() < cpu){
scePowerSetCpuClockFrequency(cpu + 1);
}
scePowerSetBusClockFrequency(bus);
if (scePowerGetBusClockFrequency() < bus){
scePowerSetBusClockFrequency(bus + 1);
}
//Check result:
curCpu = scePowerGetCpuClockFrequency();
curBus = scePowerGetBusClockFrequency();
if (curCpu == cpu && curBus == bus){
snprintf(text, sizeof(text), "OK: cpu %i bus %i \n", cpu, bus);
sceIoWrite(logFile, text, strlen(text));
ok++;
}else if (curCpu != resetCpu && curBus != resetBus){
snprintf(text, sizeof(text), "CHANGED: cpu %i (%i) bus %i (%i)\n", curCpu, cpu, curBus, bus);
sceIoWrite(logFile, text, strlen(text));
}
}
}
sceIoClose(logFile);
pspDebugScreenPrintf("\n\nFound %i valid combination\n", ok);
pspDebugScreenPrintf("Check the log\n");
pspDebugScreenPrintf("Press X to quit\n");
SceCtrlData pad;
while(runningFlag){
sceCtrlReadBufferPositive(&pad, 1);
if (pad.Buttons & PSP_CTRL_CROSS){
break;
}
}
sceKernelExitGame();
return 0;
}
I included systemctrl.h and linked pspsystemctrl_kernel, but I get and "undefined reference" error during compilation.
Where's the function sctrlHENSetSpeed? :)
Many thanks.
Ciaooo
Sakya
if you import function in c++, please add before your extern imported functions.
Code: Select all
extern "C"
Hi! :)
My code is C not C++, what are you referring to?
Ciaooo
Sakya
Sorry, I cannot understand. :)aeolusc wrote:if you import function in c++, please addbefore your extern imported functions.Code: Select all
extern "C"
My code is C not C++, what are you referring to?
Ciaooo
Sakya
Thanks. So the value I was using is right. Good to know. I might have to disassemble the clock code to see what the bloody hell is going on. Exiting to the XMB is enough to turn off the ME where you can change the clock again, so there is SOME way to turn off the ME to change the clock.sakya wrote:Hi! :)sceSysregMeBusClockDisable should be sceSysreg_driver_07881A0B in kernel 3.71J.F. wrote:I posted a request for the nid for disabling the clock to the ME
Ciaooo
Sakya
disasm sctrlHenSetSpeed, translated to C codes:
I'm curious about what does the 2 unnamed functions do....
Code: Select all
int (* scePowerSetClockFrequency2)(int cpufreq, int ramfreq, int busfreq);
int (* scePowerIsBatteryCharging)(void);
void (* scePower_driver_A09FC577)(int);
void (* scePower_driver_191A3848)(int);
void sctrlHENSetSpeed(int cpu, int bus)
{
static int inited = 0;
if(!inited)
{
scePowerSetClockFrequency2 = (void *)FindProc("scePower_Service", "scePower", 0x545A7F3C);
scePowerIsBatteryCharging = (void *)FindProc("scePower_Service", "scePower", 0x1E490401);
scePower_driver_A09FC577 = (void *)FindProc("scePower_Service", "scePower_driver", 0xA09FC577);
scePower_driver_191A3848 = (void *)FindProc("scePower_Service", "scePower_driver", 0x191A3848);
inited = 1;
}
scePowerSetClockFrequency2(cpu, cpu, bus);
if(scePowerIsBatteryCharging() != 0)
return;
static int ps1 = 0;
if(ps1 == 0)
{
scePower_driver_A09FC577(1);
ps1 = 1;
return;
}
static int ps2 = 0;
if(ps2 == 0)
{
ps1 = 0;
ps2 = 1;
return;
}
scePower_driver_191A3848(0);
ps1 = 0;
ps2 = 0;
}
you have disassembled more than that function and you have gone through the slim usb charge code. Since the function is not called directly, but is done through a systimer, probably prxtool couldn't detect it as a function. (that's something tyranid has to look ;), and you thought it was part of same function.
Btw, those functions nids prior to 3.71 were:
0x733F973B -> scePowerBatteryEnableUsbCharging
0x90285886 -> scePowerBatteryDisableUsbCharging
I'm attacking power.prx with the nidcracker today, 7 results atm :D
Btw, those functions nids prior to 3.71 were:
0x733F973B -> scePowerBatteryEnableUsbCharging
0x90285886 -> scePowerBatteryDisableUsbCharging
I'm attacking power.prx with the nidcracker today, 7 results atm :D
Here's my test program. It shows that the bus clock does change, but has a very limited range on the Slim. If you always try to set the clock(s) using scePowerSetClockFrequency(cpu, cpu, cpu/2); the cpu clock will basically follow whatever value you're passing in. the bus clock will change as well, but not as widely as the cpu clock. The mimum value for the bus seems to be 95, and the maximum 166. The cpu clock will go down to 18 (with the bus staying at 95), and I've gone up to 333. I haven't tried going beyond 333, but I've heard the slim will go farther.
Code: Select all
#include <pspsdk.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <pspiofilemgr.h>
#include <pspdebug.h>
#include <psppower.h>
#include <pspdisplay.h>
#include <psprtc.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define printf pspDebugScreenPrintf
#define VERS 1
#define REVS 0
PSP_MODULE_INFO("CPUClockTest", 0, VERS, REVS);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
void wait_release(unsigned int buttons)
{
SceCtrlData pad;
sceCtrlReadBufferPositive(&pad, 1);
while (pad.Buttons & buttons)
{
sceKernelDelayThread(100000);
sceCtrlReadBufferPositive(&pad, 1);
}
}
unsigned int wait_press(unsigned int buttons)
{
SceCtrlData pad;
sceCtrlReadBufferPositive(&pad, 1);
while (1)
{
if (pad.Buttons & buttons)
return pad.Buttons & buttons;
sceKernelDelayThread(100000);
sceCtrlReadBufferPositive(&pad, 1);
}
return 0; /* never reaches here, again, just to suppress warning */
}
int main(void)
{
u32 b;
int cpu, bus, bmark;
pspDebugScreenInit();
pspDebugScreenSetBackColor(0x00000000);
pspDebugScreenSetTextColor(0x00ffffff);
pspDebugScreenClear();
sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL);
while (1)
{
pspDebugScreenClear();
printf("\n CPU Clock Test - press O to exit\n\n");
cpu = scePowerGetCpuClockFrequency();
bus = scePowerGetBusClockFrequency();
printf(" The current CPU/BUS speed is %d/%d MHz\n", cpu, bus);
b = wait_press(0xffff);
wait_release(b);
if (b & PSP_CTRL_CIRCLE)
break;
if (b & PSP_CTRL_RTRIGGER)
scePowerSetClockFrequency(333, 333, 166);
if (b & PSP_CTRL_LTRIGGER)
scePowerSetClockFrequency(33, 33, 16);
if (b & PSP_CTRL_RIGHT)
{
cpu++;
scePowerSetClockFrequency(cpu, cpu, cpu/2);
}
if (b & PSP_CTRL_LEFT)
{
cpu--;
scePowerSetClockFrequency(cpu, cpu, cpu/2);
}
if (b & PSP_CTRL_UP)
{
cpu += 10;
scePowerSetClockFrequency(cpu, cpu, cpu/2);
}
if (b & PSP_CTRL_DOWN)
{
cpu -= 10;
scePowerSetClockFrequency(cpu, cpu, cpu/2);
}
sceKernelDelayThread(100*1000);
}
sceKernelDelayThread(3*1000*1000);
sceKernelExitGame();
return 0; /* never reaches here, again, just to suppress warning */
}
Hi! :)
I'm not on a slim PSP, it's a kernel 3.71 "function". :D
Ciaooo
Sakya
In my tests also I can change the bus, but only from 111 to 95 (nevere tried higer values), the problem is that I want to set it at 54mhz. :)J.F. wrote:Here's my test program. It shows that the bus clock does change, but has a very limited range on the Slim.
I'm not on a slim PSP, it's a kernel 3.71 "function". :D
Ciaooo
Sakya
It's quite possible that Sony found that decreasing the bus clock didn't save any power, so there was no reason to allow a full range like with the CPU clock. It could also be a Slim problem - lower than 95 MHz makes the Slim unstable and Sony was too lazy to make the function discern between the Slim and Phat.sakya wrote:Hi! :)In my tests also I can change the bus, but only from 111 to 95 (nevere tried higer values), the problem is that I want to set it at 54mhz. :)J.F. wrote:Here's my test program. It shows that the bus clock does change, but has a very limited range on the Slim.
I'm not on a slim PSP, it's a kernel 3.71 "function". :D
Ciaooo
Sakya
Sorry to reopen and old thread.
I have a quick question. I'm likely doing something stupid and not realizing it.
Like this I can hit Home and exit fine:
But if I uncomment SetCPUSpeed(); in Initialise(); then upon actually trying to exit via the home button it freezes. This is on a Slim just for reference. I'm starting a new project along with the one I'm currently working on and just wondering if there's something I'm missing.
Edit: If I change "sceKernelSleepThread();" to:
while(1)
{
sceKernelDelayThread(1);
}
It works as it should... this seems like odd behavior to me.
Like this I can hit Home and exit fine:
Code: Select all
//*************************************************************************************
// Sets up the CPU Frequency
//*************************************************************************************
static void SetCPUSpeed()
{
printf( "Cpu was: %dMHz, Bus: %dMHz\n", scePowerGetCpuClockFrequency(), scePowerGetBusClockFrequency() );
if (scePowerSetClockFrequency(333, 333, 166) != 0)
{
printf( "Could not set CPU to 333MHz\n" );
}
printf( "Cpu now: %dMHz, Bus: %dMHz\n", scePowerGetCpuClockFrequency(), scePowerGetBusClockFrequency() );
}
//*************************************************************************************
// Do All of our pre-app initialisation
//*************************************************************************************
static bool Initialise()
{
// SetCPUSpeed();
SetupCallbacks();
sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
return true;
}
//*************************************************************************************
//
//*************************************************************************************
int main(int argc, char* argv[])
{
if( Initialise() )
{
sceKernelSleepThread();
}
return 0; //Should never reach here just to suppress the warning.
}
Edit: If I change "sceKernelSleepThread();" to:
while(1)
{
sceKernelDelayThread(1);
}
It works as it should... this seems like odd behavior to me.