psx.wiki

BIOS Events

Event management service that reports interrupts, exceptions and device completion.

BIOS Events
Control blockEvCB, 0x1C bytes
Default count16 (EVENT = 10)

Overview

An event is either a CPU exception or an interrupt from an external device. Because events occur asynchronously with the main program, there are two ways of dealing with them: polling to see whether an event has occurred, or installing an event handler that the kernel executes automatically when the event occurs.1 The event management service of the PS-X OS controls program execution triggered by these events.2 The kernel and the libraries also deliver events of their own for file I/O and device completion.34

An event is specified by two 32-bit integers called the cause descriptor and the event type. OpenEvent() takes the cause descriptor, the event type, the event mode and the address of the handler function, and returns a 32-bit event descriptor that identifies the event to the other functions.3 psx-spx calls the cause descriptor the class and the event type the spec.5 The event is triggered only when both values match.5

Event handlers execute in interrupt context on a 4K interrupt stack in the kernel's reserved memory. When a handler completes its processing it calls ReturnFromException(), which restores the registers and returns to the previous context.13 A handler may instead enable interrupts with ExitCriticalSection() and continue as the main flow. In this case the user must provide a stack allocated before the interrupt, and the stack is changed with SetSp().3

Event Status

An event has one of four statuses.6 Before it is opened its status is EvStUNUSED. OpenEvent() makes it EvStWAIT, and EnableEvent() makes it EvStACTIVE, in which the event may occur. DisableEvent() returns an EvStACTIVE or EvStALREADY event to EvStWAIT, and the previous state is not saved.6

Table 1: Event conditions
Macro Contents Generation EvCB status value
EvStUNUSED Not opened Prohibited 0x0000
EvStWAIT Event generation prohibited Prohibited 0x1000
EvStACTIVE Event not yet generated Possible 0x2000
EvStALREADY Event already generated Prohibited 0x4000

The macros and their meanings are from the Run-Time Library Overview.6 psx-spx gives the EvCB status values as 0x0000 free, 0x1000 disabled, 0x2000 enabled and busy, and 0x4000 enabled and ready, which correspond in meaning to the four Sony statuses.7

Event Modes

An event has one of two modes, chosen when it is opened.6 With EvMdINTR the handler function is called when the event occurs and the event stays EvStACTIVE. With EvMdNOINTR no handler is called, the event becomes EvStALREADY, and the program must test for it.6

Table 2: Event modes
Macro Value Status after generation Handler function
EvMdINTR 0x1000 EvStACTIVE Active
EvMdNOINTR 0x2000 EvStALREADY Not active

psx-spx gives mode 0x1000 as "execute function and stay busy" and mode 0x2000 as "no function and mark ready", which correspond to EvMdINTR and EvMdNOINTR.8 Because an EvMdINTR event never becomes EvStALREADY, WaitEvent() on such an event never returns.5

Generating and Clearing Events

DeliverEvent() switches every enabled event with the given cause descriptor and event type to EvStALREADY. Events in EvMdINTR mode have their handler called inside DeliverEvent().6 Clearing an event switches it from EvStALREADY back to EvStACTIVE. UnDeliverEvent() takes a cause descriptor and an event type and clears all matching events, while TestEvent() and WaitEvent() clear the one event they are given.6910 An event must be cleared with UnDeliverEvent() before it is issued again.6

DeliverEvent() scans every EvCB, even when all events are disabled. A larger EVENT value in SYSTEM.CNF therefore slows down every event delivery.5 OpenEvent(), CloseEvent(), DeliverEvent() and UnDeliverEvent() must be executed in a critical section.11121314

A program may define its own events with the DescUEV macro. The calls take the forms DeliverEvent(DescUEV|my_event_num, my_event_spec) and OpenEvent(DescUEV|my_event_num, my_event_spec, EvMdNOINTR, NULL).6

Event Functions

Table 3: Event functions
Function BIOS Explanation
OpenEvent(desc, spec, mode, func) B(08h) Secures an EvCB and returns the event descriptor (0xF1000000 and up), or -1115
CloseEvent(event) B(09h) Releases the EvCB12
EnableEvent(event) B(0Ch) Changes the status to EvStACTIVE15
DisableEvent(event) B(0Dh) Changes the status to EvStWAIT16
WaitEvent(event) B(0Ah) Waits for the event, then restores EvStACTIVE; returns 0 if the event is disabled105
TestEvent(event) B(0Bh) Returns 1 and restores EvStACTIVE if the event has occurred, 0 otherwise9
DeliverEvent(ev1, ev2) B(07h) Generates an event13
UnDeliverEvent(ev1, ev2) B(20h) Returns matching EvMdNOINTR events from EvStALREADY to EvStACTIVE14

Sony documents CloseEvent(), EnableEvent() and DisableEvent() as returning 1 on success and 0 on failure.121516 psx-spx finds that the BIOS functions always return 1 and do so even for an unused or invalid descriptor.5 The return value of WaitEvent() is also unreliable: it may return 0 when the event becomes ready shortly after the call.5 In a program with several threads, a loop that calls TestEvent() and ChangeTh() lets other threads run, whereas WaitEvent() holds the CPU until the event occurs.5

Event Control Block

The kernel keeps the information about an event in an event control block. The EvCB array is reached through ToT entry 4 at address 0x00000120.173

struct EvCB {              /* event control block */
    unsigned long desc;    /* cause descriptor */
    long status;           /* status */
    long spec;             /* event type */
    long mode;             /* mode */
    long (*FHandler)();    /* function format handler */
    long system[2];        /* system reserved */
};
Table 4: EvCB layout
Offset Size Field Contents
0x00 4 desc Cause descriptor (class)
0x04 4 status 0x0000, 0x1000, 0x2000 or 0x4000
0x08 4 spec Event type
0x0C 4 mode 0x1000 or 0x2000
0x10 4 FHandler Handler function, or 0
0x14 8 system Not used

The structure is from the Run-Time Library Reference, and the offsets and values are from psx-spx.187 An event descriptor converts to its EvCB as [0x120] + (event AND 0xFFFF) * 0x1C.19

Cause Descriptors

The cause descriptors related to the kernel library are shown below. Other events are described in the individual libraries.3

Table 5: Cause descriptors (kernel library)
Cause descriptor Contents Event type
RCntCNT0 to RCntCNT3 Root counter interrupt EvSpINT
File descriptor File input/output EvSpEIO
File descriptor File close EvSpCLOSE
HwCdRom CD-ROM decoder interrupt EvSpUNKNOWN
HwSPU SPU interrupt EvSpTRAP
HwGPU GPU interrupt EvSpTRAP
HwPIO Extension parallel port interrupt EvSpTRAP
HwSIO Extension serial port interrupt EvSpTRAP
HwCPU Exceptions EvSpTRAP
DescUEV, m User-defined event (m = 0 to 0xFFFF) Optional

The numeric classes used by the BIOS are shown below.20

Table 6: Event classes
Class Source
0x0000000x Memory Card file, for file descriptor x
0xF0000001 IRQ0, vertical blank
0xF0000002 IRQ1, GPU
0xF0000003 IRQ2, CD-ROM decoder
0xF0000004 IRQ3, DMA controller
0xF0000005 IRQ4, timer 0
0xF0000006 IRQ5 and IRQ6, timer 1 and timer 2
0xF0000008 IRQ7, controller and Memory Card
0xF0000009 IRQ9, SPU
0xF000000A IRQ10, PIO
0xF000000B IRQ8, SIO
0xF0000010 Exception (break, bad syscall, overflow, memory error)
0xF0000011 Memory Card, lower level BIOS functions
0xF2000000 Root counter 0 (dot clock)
0xF2000001 Root counter 1 (horizontal retrace)
0xF2000002 Root counter 2 (one-eighth of the system clock)
0xF2000003 Root counter 3 (vertical retrace, a software counter)
0xF4000001 Memory Card, higher level BIOS functions
0xF4000002 libmath

psx-spx also reports classes 0xF1xxxxxx for events, 0xF3xxxxxx for user events and 0xFFxxxxxx for threads, which the BIOS does not use.20

Event Types

The numeric event types are shown below.21

Table 7: Event types
Spec Meaning
0x0001 Counter becomes zero
0x0002 Interrupted
0x0004 End of I/O
0x0008 File was closed
0x0010 Command acknowledged
0x0020 Command completed
0x0040 Data ready
0x0080 Data end
0x0100 Time out
0x0200 Unknown command
0x0400 End of read buffer
0x0800 End of write buffer
0x1000 General interrupt
0x2000 New device
0x4000 System call instruction
0x8000 Error happened
0x8001 Previous write error happened
0x0301 Domain error in libmath
0x0302 Range error in libmath

Events Delivered by the BIOS

The BIOS opens five CD-ROM events for itself, with class 0xF0000003 and types 0x10, 0x20, 0x40, 0x80 and 0x8000. The other events below are delivered by the BIOS for a game to open.4

Table 8: Events delivered by the BIOS
Class Spec Meaning
0xF0000003 0x0010 CD-ROM DMA finished (all sectors)
0xF0000003 0x0080 CD-ROM INT4, end of disc reached
0x0000000x 0x0004 Memory Card file x done
0xF4000001 0x0004 Memory Card done
0xF4000001 0x0100 Memory Card busy error
0xF4000001 0x2000 Memory Card ejected or unformatted
0xF4000001 0x8000 Memory Card write or general error
0xF0000011 0x0004 Memory Card hardware I/O finished
0xF0000011 0x0100 Memory Card hardware busy error
0xF0000011 0x2000, 0x8000, 0x8001 Memory Card hardware errors
0xF2000000 0x0002 Timer 0 (IRQ4)
0xF2000001 0x0002 Timer 1 (IRQ5)
0xF2000002 0x0002 Timer 2 (IRQ6)
0xF2000003 0x0002 Vertical blank (IRQ0)
0xF0000010 0x1000 Unknown exception
0xF0000010 0x4000 Unknown syscall

The default interrupt handler also delivers class 0xF0000001 to 0xF000000B with type 0x1000. psx-spx advises against using these events, because the handler does not record which interrupt occurred and may deliver them at random.422 It also reports timer 2 with the same class as timer 1.4

Interrupt Handling

When an interrupt or exception occurs, the kernel saves the registers in the execution TCB as the main flow context. Processing begins at address 0x00000080, which jumps to the kernel interrupt dispatcher, and the dispatcher calls the routine for the interrupt. When processing is complete, the main flow registers are restored and the main flow resumes.23

The dispatcher keeps four priority chains of interrupt handlers and calls every handler in order. The first handler called is the first element of chain 0. Each handler checks the interrupt status register at 0x1F801070 for its own source.22 A handler that has processed and acknowledged its interrupt may call ReturnFromException() to skip the handlers of lower priority.22 The default chains are shown below.22

Table 9: Default interrupt priority chains
Priority Handlers
0 CdromDmaIrq, CdromIoIrq, SyscallException
1 CardSpecificIrq, VblankIrq, Timer2Irq, Timer1Irq, Timer0Irq
2 PadCardIrq
3 DefInt

Because the dispatcher does not record the incoming interrupt flags, a high priority handler may reject an interrupt that has not yet been flagged while a lower priority handler later processes or acknowledges it. psx-spx therefore recommends only one handler for each interrupt source.22 The kernel does not support nested exceptions: the registers are saved in the current TCB and the exception stack has a fixed start address, so a nested exception overwrites both.22

HookEntryInt() installs a function that runs after the handler chains have been fully processed. It takes a structure in the setjmp() format, and the hook is called with R2 = 1 and should end with ReturnFromException(). ResetEntryInt() restores the default structure, whose RA is ReturnFromException().22

The cautions and prohibitions for code in interrupt context are on the PS-X OS page.

References


  1. ^ a b Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-9.

  2. ^ Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 3-3.

  3. ^ a b c d e f Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-10, Table 2-12.

  4. ^ a b c d psx-spx. Kernel (BIOS), BIOS Event Summary. https://psx-spx.consoledev.net/kernelbios/

  5. ^ a b c d e f g h i psx-spx. Kernel (BIOS), BIOS Event Functions. https://psx-spx.consoledev.net/kernelbios/

  6. ^ a b c d e f g h i Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-11, Table 2-13, Table 2-14.

  7. ^ a b psx-spx. Kernel (BIOS), BIOS Control Blocks, Event Control Blocks. https://psx-spx.consoledev.net/kernelbios/

  8. ^ psx-spx. Kernel (BIOS), BIOS Event Functions, Event modes. https://psx-spx.consoledev.net/kernelbios/

  9. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-73, TestEvent.

  10. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-76, WaitEvent.

  11. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-54, OpenEvent.

  12. ^ a b c Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-15, CloseEvent.

  13. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-17, DeliverEvent.

  14. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-75, UnDeliverEvent.

  15. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-20, EnableEvent.

  16. ^ a b Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-18, DisableEvent.

  17. ^ Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-4.

  18. ^ Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-4, EvCB.

  19. ^ psx-spx. Kernel (BIOS), Table of Tables. https://psx-spx.consoledev.net/kernelbios/

  20. ^ a b psx-spx. Kernel (BIOS), BIOS Event Functions, Event Classes. https://psx-spx.consoledev.net/kernelbios/

  21. ^ psx-spx. Kernel (BIOS), BIOS Event Functions, Event Specs. https://psx-spx.consoledev.net/kernelbios/

  22. ^ a b c d e f g psx-spx. Kernel (BIOS), BIOS Interrupt/Exception Handling. https://psx-spx.consoledev.net/kernelbios/

  23. ^ Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-6.

Categories: System software