Handwritten asm: OS functions, libm_vals

This commit is contained in:
Tharo 2025-08-16 17:36:22 +01:00
parent 28b60fc00c
commit 76f8d6b670
12 changed files with 479 additions and 9 deletions

80
include/PR/rdb.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef PR_RDB_H
#define PR_RDB_H
/* U64 side address */
#define RDB_BASE_REG 0xC0000000
#define RDB_WRITE_INTR_REG (RDB_BASE_REG + 0x8)
#define RDB_READ_INTR_REG (RDB_BASE_REG + 0xC)
#define RDB_BASE_VIRTUAL_ADDR 0x80000000
/* packet type Have six bits, so can have up to 63 types */
#define RDB_TYPE_INVALID 0
#define RDB_TYPE_GtoH_PRINT 1
#define RDB_TYPE_GtoH_FAULT 2
#define RDB_TYPE_GtoH_LOG_CT 3
#define RDB_TYPE_GtoH_LOG 4
#define RDB_TYPE_GtoH_READY_FOR_DATA 5
#define RDB_TYPE_GtoH_DATA_CT 6
#define RDB_TYPE_GtoH_DATA 7
#define RDB_TYPE_GtoH_DEBUG 8
#define RDB_TYPE_GtoH_RAMROM 9
#define RDB_TYPE_GtoH_DEBUG_DONE 10
#define RDB_TYPE_GtoH_DEBUG_READY 11
#define RDB_TYPE_GtoH_KDEBUG 12
#define RDB_TYPE_GtoH_PROF_DATA 22
#define RDB_TYPE_HtoG_LOG_DONE 13
#define RDB_TYPE_HtoG_DEBUG 14
#define RDB_TYPE_HtoG_DEBUG_CT 15
#define RDB_TYPE_HtoG_DATA 16
#define RDB_TYPE_HtoG_DATA_DONE 17
#define RDB_TYPE_HtoG_REQ_RAMROM 18
#define RDB_TYPE_HtoG_FREE_RAMROM 19
#define RDB_TYPE_HtoG_KDEBUG 20
#define RDB_TYPE_HtoG_PROF_SIGNAL 21
#define RDB_PROF_ACK_SIG 1
#define RDB_PROF_FLUSH_SIG 2
#define PROF_BLOCK_SIZE 2048
#define RDB_LOG_MAX_BLOCK_SIZE 0x8000
#define RDB_DATA_MAX_BLOCK_SIZE 0x8000
/* GIO side address */
#define GIO_RDB_BASE_REG 0xBF480000
#define GIO_RDB_WRITE_INTR_REG (GIO_RDB_BASE_REG + 0x8)
#define GIO_RDB_READ_INTR_REG (GIO_RDB_BASE_REG + 0xC)
/* minor device number */
#define GIO_RDB_PRINT_MINOR 1
#define GIO_RDB_DEBUG_MINOR 2
/* interrupt bit */
#define GIO_RDB_WRITE_INTR_BIT 0x80000000
#define GIO_RDB_READ_INTR_BIT 0x40000000
/* debug command */
#define DEBUG_COMMAND_NULL 0
#define DEBUG_COMMAND_MEMORY 1
#define DEBUG_COMMAND_REGISTER 2
#define DEBUG_COMMAND_INVALID 255
/* debug state */
#define DEBUG_STATE_NULL 0
#define DEBUG_STATE_RECEIVE 1
#define DEBUG_STATE_INVALID 255
#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS)
typedef struct {
unsigned type : 6; /* 0: invalid, 1: print, 2: debug */
unsigned length : 2; /* 1, 2, or 3 */
char buf[3]; /* character buffer */
} rdbPacket;
#endif
#endif

View File

@ -79,7 +79,7 @@ beginseg
include "$(BUILD_DIR)/src/libultra/os/virtualtophysical.o"
include "$(BUILD_DIR)/src/libultra/os/getsr.o"
include "$(BUILD_DIR)/src/libultra/os/setsr.o"
include "$(BUILD_DIR)/asm/boot/writebackdcache.text.o"
include "$(BUILD_DIR)/src/libultra/os/writebackdcache.o"
include "$(BUILD_DIR)/src/libultra/os/initialize.o"
include "$(BUILD_DIR)/src/libultra/debug/kdebugserver.o"
include "$(BUILD_DIR)/src/libultra/os/parameters.o"
@ -101,7 +101,7 @@ beginseg
include "$(BUILD_DIR)/src/libultra/gu/lookat.o"
include "$(BUILD_DIR)/src/libultra/io/pfsallocatefile.o"
include "$(BUILD_DIR)/src/libultra/os/stoptimer.o"
include "$(BUILD_DIR)/asm/boot/probetlb.text.o"
include "$(BUILD_DIR)/src/libultra/os/probetlb.o"
include "$(BUILD_DIR)/src/libultra/io/pimgr.o"
include "$(BUILD_DIR)/src/libultra/io/piacs.o"
include "$(BUILD_DIR)/src/libultra/io/devmgr.o"
@ -119,14 +119,14 @@ beginseg
include "$(BUILD_DIR)/src/libultra/gu/lookathil.o"
include "$(BUILD_DIR)/src/libultra/libc/xprintf.o"
include "$(BUILD_DIR)/src/libultra/voice/voicecleardictionary.o"
include "$(BUILD_DIR)/asm/boot/unmaptlball.text.o"
include "$(BUILD_DIR)/src/libultra/os/unmaptlball.o"
include "$(BUILD_DIR)/src/libultra/io/epidma.o"
include "$(BUILD_DIR)/src/libultra/voice/voicecontread2.o"
include "$(BUILD_DIR)/src/libultra/voice/voicecrc.o"
include "$(BUILD_DIR)/src/libultra/libc/string.o"
include "$(BUILD_DIR)/src/libultra/os/createmesgqueue.o"
include "$(BUILD_DIR)/asm/boot/invalicache.text.o"
include "$(BUILD_DIR)/asm/boot/invaldcache.text.o"
include "$(BUILD_DIR)/src/libultra/os/invalicache.o"
include "$(BUILD_DIR)/src/libultra/os/invaldcache.o"
include "$(BUILD_DIR)/src/libultra/os/timerintr.o"
include "$(BUILD_DIR)/src/libultra/voice/voicecontread36.o"
include "$(BUILD_DIR)/src/libultra/io/sp.o"
@ -161,7 +161,7 @@ beginseg
include "$(BUILD_DIR)/src/libultra/os/resetglobalintmask.o"
include "$(BUILD_DIR)/src/libultra/io/pfsdeletefile.o"
include "$(BUILD_DIR)/src/libultra/gu/ortho.o"
include "$(BUILD_DIR)/asm/boot/interrupt.text.o"
include "$(BUILD_DIR)/src/libultra/os/interrupt.o"
include "$(BUILD_DIR)/src/libultra/vimodes/vimodentsclan1.o"
include "$(BUILD_DIR)/src/libultra/vimodes/vimodempallan1.o"
include "$(BUILD_DIR)/src/libultra/io/vi.o"
@ -188,14 +188,14 @@ beginseg
include "$(BUILD_DIR)/src/libultra/io/pfschecker.o"
include "$(BUILD_DIR)/src/libultra/io/aigetlen.o"
include "$(BUILD_DIR)/src/libultra/io/epiwrite.o"
include "$(BUILD_DIR)/asm/boot/maptlbrdb.text.o"
include "$(BUILD_DIR)/src/libultra/os/maptlbrdb.o"
include "$(BUILD_DIR)/src/libultra/os/yieldthread.o"
include "$(BUILD_DIR)/src/libultra/mgu/translate.o"
include "$(BUILD_DIR)/src/libultra/os/getcause.o"
include "$(BUILD_DIR)/src/libultra/io/contramwrite.o"
include "$(BUILD_DIR)/src/libultra/io/epirawwrite.o"
include "$(BUILD_DIR)/src/libultra/os/settimer.o"
include "$(BUILD_DIR)/data/boot/libm_vals.rodata.o"
include "$(BUILD_DIR)/src/libultra/gu/libm_vals.o"
include "$(BUILD_DIR)/src/libultra/libc/xldtob.o"
include "$(BUILD_DIR)/src/libultra/libc/ldiv.o"
include "$(BUILD_DIR)/src/libultra/libc/xlitob.o"
@ -204,7 +204,7 @@ beginseg
include "$(BUILD_DIR)/src/libultra/io/spsetstat.o"
include "$(BUILD_DIR)/src/libultra/io/vimgr.o"
include "$(BUILD_DIR)/src/libultra/io/vigetcurrcontext.o"
include "$(BUILD_DIR)/asm/boot/writebackdcacheall.text.o"
include "$(BUILD_DIR)/src/libultra/os/writebackdcacheall.o"
include "$(BUILD_DIR)/src/libultra/os/getcurrfaultthread.o"
include "$(BUILD_DIR)/src/libultra/voice/voicemaskdictionary.o"
include "$(BUILD_DIR)/src/libultra/mgu/mtxf2l.o"

View File

@ -0,0 +1,8 @@
#include "PR/asm.h"
#include "PR/regdef.h"
.rdata
DATA(__libm_qnan_f)
.word 0x7F810000
ENDDATA(__libm_qnan_f)

View File

@ -0,0 +1,45 @@
#include "PR/asm.h"
#include "PR/regdef.h"
#include "PR/R4300.h"
#include "PR/os_thread.h"
.text
LEAF(__osDisableInt)
la t2, __OSGlobalIntMask
lw t3, (t2)
and t3, t3, SR_IMASK
MFC0( t0, C0_SR)
and t1, t0, ~SR_IE
MTC0( t1, C0_SR)
and v0, t0, SR_IE
lw t0, (t2)
and t0, t0, SR_IMASK
.set noreorder
beq t0, t3, No_Change_Global_Int
/*! @bug this la should be lw, it may never come up in practice as to reach this code
*! the CPU bits of __OSGlobalIntMask must have changed while this function is running.
*/
la t2, __osRunningThread
lw t1, THREAD_SR(t2)
and t2, t1, SR_IMASK
and t2, t2, t0
.set reorder
and t1, t1, ~SR_IMASK
or t1, t1, t2
and t1, t1, ~SR_IE
MTC0( t1, C0_SR)
NOP
NOP
No_Change_Global_Int:
jr ra
END(__osDisableInt)
LEAF(__osRestoreInt)
MFC0( t0, C0_SR)
or t0, t0, a0
MTC0( t0, C0_SR)
NOP
NOP
jr ra
END(__osRestoreInt)

View File

@ -0,0 +1,80 @@
#include "PR/asm.h"
#include "PR/regdef.h"
#include "PR/R4300.h"
.text
/**
* void osInvalDCache(void* vaddr, s32 nbytes);
*
* Invalidates the CPU Data Cache for `nbytes` at `vaddr`.
* The cache is not automatically synced with physical memory, so cache
* lines must be invalidated to ensure old data is not used in place of
* newly available data supplied by an external agent in a DMA operation.
*
* If `vaddr` is not aligned to a cache line boundary, or nbytes is not a
* multiple of the data cache line size (16 bytes) a larger region is
* invalidated.
*
* If the amount to invalidate is at least the data cache size (DCACHE_SIZE),
* the entire data cache is invalidated.
*/
LEAF(osInvalDCache)
/* If the amount to invalidate is less than or equal to 0, return immediately */
blez a1, 3f
/* If the amount to invalidate is as large as or larger than
* the data cache size, invalidate all */
li t3, DCACHE_SIZE
bgeu a1, t3, 4f
/* Ensure end address doesn't wrap around and end up smaller
* than the start address */
move t0, a0
addu t1, a0, a1
bgeu t0, t1, 3f
/* Mask start with cache line */
addiu t1, t1, -DCACHE_LINESIZE
andi t2, t0, DCACHE_LINEMASK
/* If mask is not zero, the start is not cache aligned */
beqz t2, 1f
/* Subtract mask result to align to cache line */
subu t0, t0, t2
/* Hit-Writeback-Invalidate unaligned part */
CACHE( (CACH_PD | C_HWBINV), (t0))
/* If that's all there is to do, return early */
bgeu t0, t1, 3f
addiu t0, t0, DCACHE_LINESIZE
1:
/* Mask end with cache line */
andi t2, t1, DCACHE_LINEMASK
/* If mask is not zero, the end is not cache aligned */
beqz t2, 2f
/* Subtract mask result to align to cache line */
subu t1, t1, t2
/* Hit-Writeback-Invalidate unaligned part */
CACHE( (CACH_PD | C_HWBINV), DCACHE_LINESIZE(t1))
/* If that's all there is to do, return early */
bltu t1, t0, 3f
/* Invalidate the rest */
2:
/* Hit-Invalidate */
CACHE( (CACH_PD | C_HINV), (t0))
.set noreorder
bltu t0, t1, 2b
addiu t0, t0, DCACHE_LINESIZE
.set reorder
3:
jr ra
4:
li t0, K0BASE
addu t1, t0, t3
addiu t1, t1, -DCACHE_LINESIZE
5:
/* Index-Writeback-Invalidate */
CACHE( (CACH_PD | C_IWBINV), (t0))
.set noreorder
bltu t0, t1, 5b
addiu t0, DCACHE_LINESIZE
.set reorder
jr ra
END(osInvalDCache)

View File

@ -0,0 +1,44 @@
#include "PR/asm.h"
#include "PR/regdef.h"
#include "PR/R4300.h"
.text
LEAF(osInvalICache)
/* If the amount to invalidate is less than or equal to 0, return immediately */
blez a1, 2f
/* If the amount to invalidate is as large as or larger than */
/* the instruction cache size, invalidate all */
li t3, ICACHE_SIZE
bgeu a1, t3, 3f
/* ensure end address doesn't wrap around and end up smaller */
/* than the start address */
move t0, a0
addu t1, a0, a1
bgeu t0, t1, 2f
/* Mask and subtract to align to cache line */
addiu t1, t1, -ICACHE_LINESIZE
andi t2, t0, ICACHE_LINEMASK
subu t0, t0, t2
1:
CACHE( (CACH_PI | C_HINV), (t0))
.set noreorder
bltu t0, t1, 1b
addiu t0, t0, ICACHE_LINESIZE
.set reorder
2:
jr ra
3:
li t0, K0BASE
addu t1, t0, t3
addiu t1, t1, -ICACHE_LINESIZE
4:
CACHE( (CACH_PI | C_IINV), (t0))
.set noreorder
bltu t0, t1, 4b
addiu t0, ICACHE_LINESIZE
.set reorder
jr ra
.set reorder
END(osInvalICache)

View File

@ -0,0 +1,31 @@
#include "PR/asm.h"
#include "PR/regdef.h"
#include "PR/R4300.h"
#include "PR/rdb.h"
.text
LEAF(osMapTLBRdb)
MFC0( t0, C0_ENTRYHI)
li t1, NTLBENTRIES
MTC0( t1, C0_INX)
MTC0( zero, C0_PAGEMASK)
li t2, (TLBLO_UNCACHED | TLBLO_D | TLBLO_V | TLBLO_G)
li t1, (RDB_BASE_REG & TLBHI_VPN2MASK)
MTC0( t1, C0_ENTRYHI)
/* Possible bug? Virtual address instead of physical address set as page frame number */
li t1, RDB_BASE_VIRTUAL_ADDR
srl t3, t1, TLBLO_PFNSHIFT
or t3, t3, t2
MTC0( t3, C0_ENTRYLO0)
li t1, TLBLO_G
MTC0( t1, C0_ENTRYLO1)
NOP
TLBWI
NOP
NOP
NOP
NOP
MTC0( t0, C0_ENTRYHI)
jr ra
END(osMapTLBRdb)

View File

@ -0,0 +1,83 @@
#include "PR/asm.h"
#include "PR/regdef.h"
#include "PR/R4300.h"
.text
/**
* u32 __osProbeTLB(void* vaddr);
*
* Searches the TLB for the physical address associated with
* the virtual address `vaddr`.
*
* Returns the physical address if found, or -1 if not found.
*/
LEAF(__osProbeTLB)
.set noreorder
/* Set C0_ENTRYHI based on supplied vaddr */
mfc0 t0, C0_ENTRYHI
and t1, t0, TLBHI_PIDMASK
and t2, a0, TLBHI_VPN2MASK
or t1, t1, t2
mtc0 t1, C0_ENTRYHI
nop
nop
nop
/* TLB probe, sets C0_INX to a value matching C0_ENTRYHI. */
/* If no match is found the TLBINX_PROBE bit is set to indicate this. */
tlbp
nop
nop
/* Read result */
mfc0 t3, C0_INX
and t3, t3, TLBINX_PROBE
/* Branch if no match was found */
bnez t3, 3f
nop
/* Read TLB, sets C0_ENTRYHI, C0_ENTRYLO0, C0_ENTRYLO1 and C0_PAGEMASK for the TLB */
/* entry indicated by C0_INX */
tlbr
nop
nop
nop
/* Calculate page size = (page mask + 0x2000) >> 1 */
mfc0 t3, C0_PAGEMASK
add t3, t3, 0x2000
srl t3, t3, 1
/* & with vaddr */
and t4, t3, a0
/* Select C0_ENTRYLO0 or C0_ENTRYLO1 */
bnez t4, 1f
add t3, t3, -1 /* make bitmask out of page size */
mfc0 v0, C0_ENTRYLO0
b 2f
nop
1:
mfc0 v0, C0_ENTRYLO1
2:
/* Check valid bit and branch if not valid */
and t5, v0, TLBLO_V
beqz t5, 3f
nop
/* Extract the Page Frame Number from the entry */
and v0, v0, TLBLO_PFNMASK
sll v0, v0, TLBLO_PFNSHIFT
/* Mask vaddr with page size mask */
and t5, a0, t3
/* Add masked vaddr to pfn to obtain the physical address */
add v0, v0, t5
b 4f
nop
3:
/* No physical address for the supplied virtual address was found, */
/* return -1 */
li v0, -1
4:
/* Restore original C0_ENTRYHI value before returning */
mtc0 t0, C0_ENTRYHI
jr ra
nop
.set reorder
END(__osProbeTLB)

View File

@ -0,0 +1,25 @@
#include "PR/asm.h"
#include "PR/regdef.h"
#include "PR/R4300.h"
.text
LEAF(osUnmapTLBAll)
MFC0( t0, C0_ENTRYHI)
li t1, (NTLBENTRIES - 1)
li t2, (K0BASE & TLBHI_VPN2MASK)
MTC0( t2, C0_ENTRYHI)
MTC0( zero, C0_ENTRYLO0)
MTC0( zero, C0_ENTRYLO1)
1:
MTC0( t1, C0_INX)
NOP
TLBWI
NOP
NOP
addi t1, t1, -1
bgez t1, 1b
MTC0( t0, C0_ENTRYHI)
jr ra
END(osUnmapTLBAll)

View File

@ -0,0 +1,54 @@
#include "PR/asm.h"
#include "PR/regdef.h"
#include "PR/R4300.h"
.text
/**
* void osWritebackDCache(void* vaddr, s32 nbytes);
*
* Writes back the contents of the data cache to main memory for `nbytes` at `vaddr`.
* If `nbytes` is as large as or larger than the data cache size, the entire cache is
* written back.
*/
LEAF(osWritebackDCache)
/* If the amount to write back is less than or equal to 0, return immediately */
blez a1, 2f
/* If the amount to write back is as large as or larger than */
/* the data cache size, write back all */
li t3, DCACHE_SIZE
bgeu a1, t3, 3f
/* ensure end address doesn't wrap around and end up smaller */
/* than the start address */
move t0, a0
addu t1, a0, a1
bgeu t0, t1, 2f
/* Mask and subtract to align to cache line */
addiu t1, t1, -DCACHE_LINESIZE
andi t2, t0, DCACHE_LINEMASK
subu t0, t0, t2
1:
CACHE( (CACH_PD | C_HWB), (t0))
.set noreorder
bltu t0, t1, 1b
addiu t0, t0, DCACHE_LINESIZE
.set reorder
2:
jr ra
/* same as osWritebackDCacheAll in operation */
3:
li t0, K0BASE
addu t1, t0, t3
addiu t1, t1, -DCACHE_LINESIZE
4:
CACHE( (CACH_PD | C_IWBINV), (t0))
.set noreorder
bltu t0, t1, 4b
addiu t0, DCACHE_LINESIZE
.set reorder
jr ra
END(osWritebackDCache)

View File

@ -0,0 +1,19 @@
#include "PR/asm.h"
#include "PR/regdef.h"
#include "PR/R4300.h"
.text
LEAF(osWritebackDCacheAll)
li t0, K0BASE
li t2, DCACHE_SIZE
addu t1, t0, t2
addiu t1, t1, -DCACHE_LINESIZE
1:
.set noreorder
cache (CACH_PD | C_IWBINV), (t0)
bltu t0, t1, 1b
addiu t0, DCACHE_LINESIZE
.set reorder
jr ra
END(osWritebackDCacheAll)

View File

@ -1,5 +1,6 @@
Warning: In Soundfont Soundfont_40: Invalid pointer indirect 0 for samplebank SampleBank_2
cc: Warning: -mips3 should not be used for ucode 32-bit compiles
as1: Warning: src/libultra/os/getintmask.s, line 38: Macro instruction used in branch delay slot
as1: Warning: src/libultra/os/interrupt.s, line 23: Macro instruction used in branch delay slot
cc: Warning: -mips3 should not be used for ucode 32-bit compiles
cc: Warning: -mips3 should not be used for ucode 32-bit compiles