From 1d97f2ea08527a9f2f716add03322656b625e7bb Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Tue, 19 Aug 2025 19:46:43 +0100 Subject: [PATCH] Handwritten asm: OS functions, libm_vals (#1821) * Handwritten asm: OS functions, libm_vals * rm hardware_regs.ld * andi -> and, addiu -> addu * CACHE macro --- include/PR/rdb.h | 80 +++++++++++++ linker_scripts/final/hardware_regs.ld | 111 ------------------ spec/spec | 18 +-- src/libultra/gu/libm_vals.s | 8 ++ src/libultra/os/getintmask.s | 6 +- src/libultra/os/interrupt.s | 45 +++++++ src/libultra/os/invaldcache.s | 80 +++++++++++++ src/libultra/os/invalicache.s | 44 +++++++ src/libultra/os/maptlbrdb.s | 31 +++++ src/libultra/os/probetlb.s | 83 +++++++++++++ src/libultra/os/unmaptlball.s | 25 ++++ src/libultra/os/writebackdcache.s | 54 +++++++++ src/libultra/os/writebackdcacheall.s | 19 +++ .../warnings_count/warnings_build_current.txt | 1 + 14 files changed, 482 insertions(+), 123 deletions(-) create mode 100644 include/PR/rdb.h delete mode 100644 linker_scripts/final/hardware_regs.ld create mode 100644 src/libultra/gu/libm_vals.s create mode 100644 src/libultra/os/interrupt.s create mode 100644 src/libultra/os/invaldcache.s create mode 100644 src/libultra/os/invalicache.s create mode 100644 src/libultra/os/maptlbrdb.s create mode 100644 src/libultra/os/probetlb.s create mode 100644 src/libultra/os/unmaptlball.s create mode 100644 src/libultra/os/writebackdcache.s create mode 100644 src/libultra/os/writebackdcacheall.s diff --git a/include/PR/rdb.h b/include/PR/rdb.h new file mode 100644 index 0000000000..5d41b035ab --- /dev/null +++ b/include/PR/rdb.h @@ -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 diff --git a/linker_scripts/final/hardware_regs.ld b/linker_scripts/final/hardware_regs.ld deleted file mode 100644 index 3e7ad405a1..0000000000 --- a/linker_scripts/final/hardware_regs.ld +++ /dev/null @@ -1,111 +0,0 @@ -// libultra OS symbols - -D_80000000 = 0x80000000; // __osExceptionPreamble -D_80000004 = 0x80000004; // __osExceptionPreamble -D_80000008 = 0x80000008; // __osExceptionPreamble -D_8000000C = 0x8000000C; // __osExceptionPreamble -D_80000010 = 0x80000010; // -D_80000020 = 0x80000020; // - -/// OS hardware registers - -// Signal Processor Registers - -D_A4040000 = 0xA4040000; // SP_MEM_ADDR_REG -D_A4040004 = 0xA4040004; // SP_DRAM_ADDR_REG -D_A4040008 = 0xA4040008; // SP_RD_LEN_REG -D_A404000C = 0xA404000C; // SP_WR_LEN_REG -D_A4040010 = 0xA4040010; // SP_STATUS_REG -D_A4040014 = 0xA4040014; // SP_DMA_FULL_REG -D_A4040018 = 0xA4040018; // SP_DMA_BUSY_REG -D_A404001C = 0xA404001C; // SP_SEMAPHORE_REG - -D_A4080000 = 0xA4080000; // SP PC - -// Display Processor Command Registers / Rasterizer Interface - -D_A4100000 = 0xA4100000; // DPC_START_REG -D_A4100004 = 0xA4100004; // DPC_END_REG -D_A4100008 = 0xA4100008; // DPC_CURRENT_REG -D_A410000C = 0xA410000C; // DPC_STATUS_REG -D_A4100010 = 0xA4100010; // DPC_CLOCK_REG -D_A4100014 = 0xA4100014; // DPC_BUFBUSY_REG -D_A4100018 = 0xA4100018; // DPC_PIPEBUSY_REG -D_A410001C = 0xA410001C; // DPC_TMEM_REG - -// Display Processor Span Registers - -D_A4200000 = 0xA4200000; // DPS_TBIST_REG / DP_TMEM_BIST -D_A4200004 = 0xA4200004; // DPS_TEST_MODE_REG -D_A4200008 = 0xA4200008; // DPS_BUFTEST_ADDR_REG -D_A420000C = 0xA420000C; // DPS_BUFTEST_DATA_REG - -// MIPS Interface Registers - -D_A4300000 = 0xA4300000; // MI_MODE_REG / MI_INIT_MODE_REG -D_A4300004 = 0xA4300004; // MI_VERSION_REG -D_A4300008 = 0xA4300008; // MI_INTR_REG -D_A430000C = 0xA430000C; // MI_INTR_MASK_REG - -// Video Interface Registers - -D_A4400000 = 0xA4400000; // VI_STATUS_REG / VI_CONTROL_REG -D_A4400004 = 0xA4400004; // VI_DRAM_ADDR_REG / VI_ORIGIN_REG -D_A4400008 = 0xA4400008; // VI_WIDTH_REG -D_A440000C = 0xA440000C; // VI_INTR_REG -D_A4400010 = 0xA4400010; // VI_CURRENT_REG -D_A4400014 = 0xA4400014; // VI_BURST_REG / VI_TIMING_REG -D_A4400018 = 0xA4400018; // VI_V_SYNC_REG -D_A440001C = 0xA440001C; // VI_H_SYNC_REG -D_A4400020 = 0xA4400020; // VI_LEAP_REG -D_A4400024 = 0xA4400024; // VI_H_START_REG -D_A4400028 = 0xA4400028; // VI_V_START_REG -D_A440002C = 0xA440002C; // VI_V_BURST_REG -D_A4400030 = 0xA4400030; // VI_X_SCALE_REG -D_A4400034 = 0xA4400034; // VI_Y_SCALE_REG - -// Audio Interface Registers - -D_A4500000 = 0xA4500000; // AI_DRAM_ADDR_REG -D_A4500004 = 0xA4500004; // AI_LEN_REG -D_A4500008 = 0xA4500008; // AI_CONTROL_REG -D_A450000C = 0xA450000C; // AI_STATUS_REG -D_A4500010 = 0xA4500010; // AI_DACRATE_REG -D_A4500014 = 0xA4500014; // AI_BITRATE_REG - -// Peripheral/Parallel Interface Registers - -D_A4600000 = 0xA4600000; // PI_DRAM_ADDR_REG -D_A4600004 = 0xA4600004; // PI_CART_ADDR_REG -D_A4600008 = 0xA4600008; // PI_RD_LEN_REG -D_A460000C = 0xA460000C; // PI_WR_LEN_REG -D_A4600010 = 0xA4600010; // PI_STATUS_REG -D_A4600014 = 0xA4600014; // PI_BSD_DOM1_LAT_REG // PI dom1 latency -D_A4600018 = 0xA4600018; // PI_BSD_DOM1_PWD_REG // PI dom1 pulse width -D_A460001C = 0xA460001C; // PI_BSD_DOM1_PGS_REG // PI dom1 page size -D_A4600020 = 0xA4600020; // PI_BSD_DOM1_RLS_REG // PI dom1 release -D_A4600024 = 0xA4600024; // PI_BSD_DOM2_LAT_REG // PI dom2 latency -D_A4600028 = 0xA4600028; // PI_BSD_DOM2_LWD_REG // PI dom2 pulse width -D_A460002C = 0xA460002C; // PI_BSD_DOM2_PGS_REG // PI dom2 page size -D_A4600030 = 0xA4600030; // PI_BSD_DOM2_RLS_REG // PI dom2 release - -// RDRAM Interface Registers - -D_A4700000 = 0xA4700000; // RI_MODE_REG -D_A4700004 = 0xA4700004; // RI_CONFIG_REG -D_A4700008 = 0xA4700008; // RI_CURRENT_LOAD_REG -D_A470000C = 0xA470000C; // RI_SELECT_REG -D_A4700010 = 0xA4700010; // RI_REFRESH_REG -D_A4700014 = 0xA4700014; // RI_LATENCY_REG -D_A4700018 = 0xA4700018; // RI_RERROR_REG -D_A470001C = 0xA470001C; // RI_WERROR_REG - -// Serial Interface Registers - -D_A4800000 = 0xA4800000; // SI_DRAM_ADDR_REG -D_A4800004 = 0xA4800004; // SI_PIF_ADDR_RD64B_REG -D_A4800008 = 0xA4800008; // reserved -D_A480000C = 0xA480000C; // reserved -D_A4800010 = 0xA4800010; // SI_PIF_ADDR_WR64B_REG -D_A4800014 = 0xA4800014; // reserved -D_A4800018 = 0xA4800018; // SI_STATUS_REG diff --git a/spec/spec b/spec/spec index c477c58463..bf203f3573 100644 --- a/spec/spec +++ b/spec/spec @@ -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" diff --git a/src/libultra/gu/libm_vals.s b/src/libultra/gu/libm_vals.s new file mode 100644 index 0000000000..fb430e1b61 --- /dev/null +++ b/src/libultra/gu/libm_vals.s @@ -0,0 +1,8 @@ +#include "PR/asm.h" +#include "PR/regdef.h" + +.rdata + +DATA(__libm_qnan_f) + .word 0x7F810000 +ENDDATA(__libm_qnan_f) diff --git a/src/libultra/os/getintmask.s b/src/libultra/os/getintmask.s index f5e7cf7704..50c187f5c5 100644 --- a/src/libultra/os/getintmask.s +++ b/src/libultra/os/getintmask.s @@ -22,13 +22,13 @@ LEAF(osGetIntMask) .set noreorder /* Extract interrupt enable bits from current SR */ mfc0 v0, C0_SR - andi v0, v0, (SR_IMASK | SR_IE) + and v0, v0, (SR_IMASK | SR_IE) /* Get value of __OSGlobalIntMask */ la t0, __OSGlobalIntMask lw t1, (t0) /* Bitwise-OR in the disabled CPU bits of __OSGlobalIntMask */ xor t0, t1, ~0 - andi t0, t0, SR_IMASK + and t0, t0, SR_IMASK or v0, v0, t0 /* Fetch MI_INTR_MASK_REG */ lw t1, PHYS_TO_K1(MI_INTR_MASK_REG) @@ -40,7 +40,7 @@ LEAF(osGetIntMask) /* Bitwise-OR in the disabled RCP bits of __OSGlobalIntMask */ srl t0, t0, RCP_IMASKSHIFT xor t0, t0, ~0 - andi t0, t0, (RCP_IMASK >> RCP_IMASKSHIFT) + and t0, t0, (RCP_IMASK >> RCP_IMASKSHIFT) or t1, t1, t0 1: /* Shift the RCP bits to not conflict with the CPU bits */ diff --git a/src/libultra/os/interrupt.s b/src/libultra/os/interrupt.s new file mode 100644 index 0000000000..3726c3a423 --- /dev/null +++ b/src/libultra/os/interrupt.s @@ -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) diff --git a/src/libultra/os/invaldcache.s b/src/libultra/os/invaldcache.s new file mode 100644 index 0000000000..2187ccf805 --- /dev/null +++ b/src/libultra/os/invaldcache.s @@ -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 */ + addu t1, t1, -DCACHE_LINESIZE + and 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 + addu t0, t0, DCACHE_LINESIZE +1: + /* Mask end with cache line */ + and 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 + addu t0, t0, DCACHE_LINESIZE +.set reorder +3: + jr ra + +4: + li t0, K0BASE + addu t1, t0, t3 + addu t1, t1, -DCACHE_LINESIZE +5: + /* Index-Writeback-Invalidate */ + CACHE( (CACH_PD | C_IWBINV), (t0)) +.set noreorder + bltu t0, t1, 5b + addu t0, DCACHE_LINESIZE +.set reorder + jr ra +END(osInvalDCache) diff --git a/src/libultra/os/invalicache.s b/src/libultra/os/invalicache.s new file mode 100644 index 0000000000..2d08408808 --- /dev/null +++ b/src/libultra/os/invalicache.s @@ -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 */ + addu t1, t1, -ICACHE_LINESIZE + and t2, t0, ICACHE_LINEMASK + subu t0, t0, t2 +1: + CACHE( (CACH_PI | C_HINV), (t0)) +.set noreorder + bltu t0, t1, 1b + addu t0, t0, ICACHE_LINESIZE +.set reorder +2: + jr ra + +3: + li t0, K0BASE + addu t1, t0, t3 + addu t1, t1, -ICACHE_LINESIZE +4: + CACHE( (CACH_PI | C_IINV), (t0)) +.set noreorder + bltu t0, t1, 4b + addu t0, ICACHE_LINESIZE +.set reorder + jr ra +.set reorder +END(osInvalICache) diff --git a/src/libultra/os/maptlbrdb.s b/src/libultra/os/maptlbrdb.s new file mode 100644 index 0000000000..e186f060db --- /dev/null +++ b/src/libultra/os/maptlbrdb.s @@ -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) diff --git a/src/libultra/os/probetlb.s b/src/libultra/os/probetlb.s new file mode 100644 index 0000000000..27b4418fa7 --- /dev/null +++ b/src/libultra/os/probetlb.s @@ -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) diff --git a/src/libultra/os/unmaptlball.s b/src/libultra/os/unmaptlball.s new file mode 100644 index 0000000000..1933f373f6 --- /dev/null +++ b/src/libultra/os/unmaptlball.s @@ -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) diff --git a/src/libultra/os/writebackdcache.s b/src/libultra/os/writebackdcache.s new file mode 100644 index 0000000000..1d77fea50e --- /dev/null +++ b/src/libultra/os/writebackdcache.s @@ -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 */ + addu t1, t1, -DCACHE_LINESIZE + and t2, t0, DCACHE_LINEMASK + subu t0, t0, t2 +1: + CACHE( (CACH_PD | C_HWB), (t0)) +.set noreorder + bltu t0, t1, 1b + addu t0, t0, DCACHE_LINESIZE +.set reorder +2: + jr ra + +/* same as osWritebackDCacheAll in operation */ +3: + li t0, K0BASE + addu t1, t0, t3 + addu t1, t1, -DCACHE_LINESIZE +4: + CACHE( (CACH_PD | C_IWBINV), (t0)) +.set noreorder + bltu t0, t1, 4b + addu t0, DCACHE_LINESIZE +.set reorder + jr ra +END(osWritebackDCache) diff --git a/src/libultra/os/writebackdcacheall.s b/src/libultra/os/writebackdcacheall.s new file mode 100644 index 0000000000..432b3b05ea --- /dev/null +++ b/src/libultra/os/writebackdcacheall.s @@ -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 + addu t1, t1, -DCACHE_LINESIZE +1: + CACHE( (CACH_PD | C_IWBINV), (t0)) +.set noreorder + bltu t0, t1, 1b + addu t0, DCACHE_LINESIZE +.set reorder + jr ra +END(osWritebackDCacheAll) diff --git a/tools/warnings_count/warnings_build_current.txt b/tools/warnings_count/warnings_build_current.txt index 96fff2b093..1d4e5da562 100644 --- a/tools/warnings_count/warnings_build_current.txt +++ b/tools/warnings_count/warnings_build_current.txt @@ -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