Page 1 of 1
Syscalls and Interrupts
Posted: Fri Feb 25, 2005 11:58 am
by misfire
With SetSyscall(s32 syscall_num, void* handler), what is the memory address where the pointer to the handler will be written to? I know that the exception service routine for syscalls resides at 0x80000180, but is there some kind of vector table used for all syscalls?
Also, what is the general difference between an interrupt and a syscall? I've got some experience in x86 assembly and never heard of syscalls...
Posted: Fri Feb 25, 2005 12:43 pm
by mharris
An interrupt is typically generated by an external event (most CPUs have an INTR or similar pin). On the PC, which is more general purpose, you have the various interrupt request levels which any hardware device can claim (e.g., IRQ3). The EE has stuff a little more hard-wired, as far as I can tell, so there are interrupts for VSync, DMA, etc. Although, I assume there's probably a way to 'rewire' things on the EE by messing around with the interrupt controller.
A system call, or syscall, is a 'trap' into the kernel -- it's typically an instruction that jumps from user-mode code to kernel mode. With Linux/i386, this is via a "software interrupt" instruction (INT 0x80), on the PS2, it's via a dedicated SYSCALL instruction. The x86 architecture doesn't have a SYSCALL instruction, but may processors have something similar (e.g., the M68K has a TRAP instruction), but the x86 software interrupts pretty much serve the same purpose, since very few PCs have 256 IRQ levels...
The 'EE Core' manual might have more info about remapping system calls, interrupt handlers, etc. but it's unlikely that you'll be able to do anything useful besides breaking the kernel.
Posted: Fri Feb 25, 2005 2:12 pm
by J.F.
Actually, the AMD64 added a fast SYSCALL instruction. 64bit linux for the AMD64 uses it for system calls. I would imagine that Windows XP64 does as well.
Re: Syscalls and Interrupts
Posted: Fri Feb 25, 2005 5:25 pm
by Guest
misfire wrote:
Also, what is the general difference between an interrupt and a syscall? I've got some experience in x86 assembly and never heard of syscalls...
A syscall is merely one type of exception. An interrupt is also a type of exception. Interrupts are normally created by hardware devices on or external to the CPU. A syscall is a software generated exception.
As others have mentioned, the primary purpose of syscall is to jump from user code to kernel level code in order to perform some lower-level function in a more protected manner. This is how operating systems maintain certain protections by forcing all kernel<->user code interactions through the syscall interface.
I am not familiar with x86 assembly, but I imagine that if it doesn't have a function specificaly called syscall then there is a similar instruction. The different protected mode priviledge rings of the x86 arch require some method to move amongst them I imagine.
Posted: Thu Mar 03, 2005 5:56 am
by misfire
Thanks for your explanations.
In the meantime, I found a way to determine the location of the syscall vector table. (I think this address varies between different BIOS versions.)
Code: Select all
u32 getSyscallVTblAddr(void)
{
const s32 syscall_num[2] = { 0xFE, 0xFF };
const u32 magic[2] = { 0x1337C0DE, 0xB16B00B5 };
u32 addr = -1;
u32 i;
SetSyscall(syscall_num[0], (void*)magic[0]);
SetSyscall(syscall_num[1], (void*)magic[1]);
ee_kmode_enter();
for (i = 0x80000000; i < 0x80080000; i += 4) {
if (!memcmp((u32*)i, magic, sizeof(magic))) {
addr = i - syscall_num[0] * 4;
break;
}
}
ee_kmode_exit();
SetSyscall(syscall_num[0], (void*)0);
SetSyscall(syscall_num[1], (void*)0);
return addr;
}
This is only interesting, if you won't to "hook" a syscall in order to extend its functionality.
EDIT: Optimized code above. Now, it seems to work for every bios.
Posted: Fri Mar 04, 2005 7:52 am
by misfire
Talking about interrupts, what is the difference between _EnableIntc() and _iEnableIntc()?
Too bad that there is no documentation on the EE syscalls. :(
Another thing. In "libcdvd.h" it says:
Code: Select all
// search for a file on disc
//
// args: file structure to get file info in
// name of file to search for (no wildcard characters)
// (should be in the form '\\SYSTEM.CNF;1')
// returns: 1 if successful
// 0 if error (or no file found)
s32 cdSearchFile(CdvdFileSpec_t *file, const char *name);
With the sample filename "\\SYSTEM.CNF;1", what's the purpose of ";1"?
Posted: Fri Mar 04, 2005 8:43 am
by Drakonite
misfire wrote:Talking about interrupts, what is the difference between _EnableIntc() and _iEnableIntc()?
Too bad that there is no documentation on the EE syscalls. :(
Another thing. In "libcdvd.h" it says:
Code: Select all
// search for a file on disc
//
// args: file structure to get file info in
// name of file to search for (no wildcard characters)
// (should be in the form '\\SYSTEM.CNF;1')
// returns: 1 if successful
// 0 if error (or no file found)
s32 cdSearchFile(CdvdFileSpec_t *file, const char *name);
With the sample filename "\\SYSTEM.CNF;1", what's the purpose of ";1"?
It's part of the iso9660 spec and is usually 'filtered out' by the low level drivers.
Posted: Fri Mar 04, 2005 8:47 am
by J.F.
misfire wrote:With the sample filename "\\SYSTEM.CNF;1", what's the purpose of ";1"?
It's part of the ISO9660 standard for filenames. All files have that stuck on the end. Why? Well, the FS that derives from allows any number of files with the same name. Each one is considered a version of the original file and the number indicates the version. In this case, there is only the original, or ";1" file. Doing it that way made handling CDs easier for the systems using that FS.
Posted: Fri Mar 18, 2005 6:14 am
by misfire
Ok, thanks for your replies.
Those i* functions are used in interrupt mode of course.
Today I've got some questions about threads. I figured out that the thread priority must be a value between 0 and 127. So, does this mean that the PS2 can handle up to 128 threads? With 0 being the highest and 0x7F the lowest priority?
Also, what does the function RotateThreadReadyQueue() do?
Posted: Fri Mar 18, 2005 7:48 am
by J.F.
You can have any number of threads with the same priority. Threads at the same priority which are ready to run share the CPU time in round-robin format. RotateThreadReadyQueue() forces the calling thread to be descheduled. The next ready thread will be run.