/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.HLE.modules;
import jpcsp.HLE.BufferInfo;
import jpcsp.HLE.BufferInfo.Usage;
import jpcsp.HLE.CanBeNull;
import jpcsp.HLE.HLEFunction;
import jpcsp.HLE.HLELogging;
import jpcsp.HLE.HLEModule;
import jpcsp.HLE.Modules;
import jpcsp.HLE.TPointer;
import jpcsp.HLE.TPointer32;
import jpcsp.HLE.BufferInfo.LengthInfo;
import jpcsp.HLE.kernel.Managers;
import jpcsp.HLE.kernel.types.SceKernelTls;
import jpcsp.hardware.Interrupts;
import org.apache.log4j.Logger;
public class Kernel_Library extends HLEModule {
public static Logger log = Modules.getLogger("Kernel_Library");
private final int flagInterruptsEnabled = 1;
private final int flagInterruptsDisabled = 0;
/**
* Suspend all interrupts.
*
* @returns The current state of the interrupt controller, to be used with ::sceKernelCpuResumeIntr().
*/
@HLEFunction(nid = 0x092968F4, version = 150)
public int sceKernelCpuSuspendIntr() {
int returnValue;
if (Interrupts.isInterruptsEnabled()) {
returnValue = flagInterruptsEnabled;
Interrupts.disableInterrupts();
} else {
returnValue = flagInterruptsDisabled;
}
return returnValue;
}
protected void hleKernelCpuResumeIntr(int flagInterrupts) {
if (flagInterrupts == flagInterruptsEnabled) {
Interrupts.enableInterrupts();
} else if (flagInterrupts == flagInterruptsDisabled) {
Interrupts.disableInterrupts();
} else {
log.warn(String.format("hleKernelCpuResumeIntr unknown flag value 0x%X", flagInterrupts));
}
}
/**
* Resume all interrupts.
*
* @param flags - The value returned from ::sceKernelCpuSuspendIntr().
*/
@HLEFunction(nid = 0x5F10D406, version = 150)
public void sceKernelCpuResumeIntr(int flagInterrupts) {
hleKernelCpuResumeIntr(flagInterrupts);
}
/**
* Resume all interrupts (using sync instructions).
*
* @param flags - The value returned from ::sceKernelCpuSuspendIntr()
*/
@HLEFunction(nid = 0x3B84732D, version = 150)
public void sceKernelCpuResumeIntrWithSync(int flagInterrupts) {
hleKernelCpuResumeIntr(flagInterrupts);
}
/**
* Determine if interrupts are suspended or active, based on the given flags.
*
* @param flags - The value returned from ::sceKernelCpuSuspendIntr().
*
* @returns 1 if flags indicate that interrupts were not suspended, 0 otherwise.
*/
@HLEFunction(nid = 0x47A0B729, version = 150)
public boolean sceKernelIsCpuIntrSuspended(int flagInterrupts) {
return flagInterrupts == flagInterruptsDisabled;
}
/**
* Determine if interrupts are enabled or disabled.
*
* @returns 1 if interrupts are currently enabled.
*/
@HLEFunction(nid = 0xB55249D2, version = 150)
public boolean sceKernelIsCpuIntrEnable() {
return Interrupts.isInterruptsEnabled();
}
@HLEFunction(nid = 0x15B6446B, version = 150, checkInsideInterrupt = true)
public int sceKernelUnlockLwMutex(TPointer workAreaAddr, int count) {
return Managers.lwmutex.sceKernelUnlockLwMutex(workAreaAddr, count);
}
@HLEFunction(nid = 0x1FC64E09, version = 380, checkInsideInterrupt = true)
public int sceKernelLockLwMutexCB(TPointer workAreaAddr, int count, @CanBeNull TPointer32 timeoutAddr) {
return Managers.lwmutex.sceKernelLockLwMutexCB(workAreaAddr, count, timeoutAddr);
}
@HLEFunction(nid = 0xBEA46419, version = 150, checkInsideInterrupt = true)
public int sceKernelLockLwMutex(TPointer workAreaAddr, int count, @CanBeNull TPointer32 timeoutAddr) {
return Managers.lwmutex.sceKernelLockLwMutex(workAreaAddr, count, timeoutAddr);
}
@HLEFunction(nid = 0xC1734599, version = 380)
public int sceKernelReferLwMutexStatus(TPointer workAreaAddr, TPointer addr) {
return Managers.lwmutex.sceKernelReferLwMutexStatus(workAreaAddr, addr);
}
@HLEFunction(nid = 0xDC692EE3, version = 380, checkInsideInterrupt = true)
public int sceKernelTryLockLwMutex(TPointer workAreaAddr, int count) {
return Managers.lwmutex.sceKernelTryLockLwMutex(workAreaAddr, count);
}
@HLEFunction(nid = 0x37431849, version = 380, checkInsideInterrupt = true)
public int sceKernelTryLockLwMutex_600(TPointer workAreaAddr, int count) {
return Managers.lwmutex.sceKernelTryLockLwMutex(workAreaAddr, count);
}
@HLELogging(level="trace")
@HLEFunction(nid = 0x1839852A, version = 150)
public int sceKernelMemcpy(@BufferInfo(lengthInfo=LengthInfo.nextNextParameter, usage=Usage.out) TPointer dst, @BufferInfo(lengthInfo=LengthInfo.nextParameter, usage=Usage.in) TPointer src, int length) {
if (dst.getAddress() != src.getAddress()) {
dst.getMemory().memcpyWithVideoCheck(dst.getAddress(), src.getAddress(), length);
}
return dst.getAddress();
}
@HLEFunction(nid = 0xFA835CDE, version = 620)
public int sceKernel_FA835CDE(int uid) {
SceKernelTls tls = Modules.ThreadManForUserModule.getKernelTls(uid);
if (tls == null) {
return 0;
}
int addr = tls.getTlsAddress();
if (log.isDebugEnabled()) {
log.debug(String.format("sceKernel_FA835CDE returning 0x%08X", addr));
}
return addr;
}
}