diff --git a/Makefile b/Makefile index 357fe7e538..ae776fb033 100644 --- a/Makefile +++ b/Makefile @@ -214,7 +214,7 @@ else ifeq ($(PLATFORM),GC) LIBULTRA_VERSION := L LIBULTRA_PATCH := 0 else ifeq ($(PLATFORM),IQUE) - CPP_DEFINES += -DPLATFORM_N64=0 -DPLATFORM_GC=0 -DPLATFORM_IQUE=1 + CPP_DEFINES += -DPLATFORM_N64=0 -DPLATFORM_GC=0 -DPLATFORM_IQUE=1 -DBBPLAYER LIBULTRA_VERSION := L LIBULTRA_PATCH := 0 else @@ -371,7 +371,7 @@ else EGCS_CFLAGS += $(CPP_DEFINES) $(GBI_DEFINES) -G 0 -nostdinc $(INC) -mcpu=vr4300 -mabi=32 -mgp32 -mfp32 -fno-PIC MIPS_VERSION := -mips2 - EGCS_CCASFLAGS := -Wall -nostdinc $(CPP_DEFINES) $(INC) -c -G 0 -Wa,-irix-symtab -D_ABIO32=1 -D_ABI64=3 -D_MIPS_SIM_ABI64=_ABI64 -D_MIPS_SIM_ABI32=_ABIO32 -DMIPSEB -D_LANGUAGE_ASSEMBLY -fno-PIC -non_shared -mcpu=4300 -mfix4300 + EGCS_CCASFLAGS := -Wall -nostdinc $(CPP_DEFINES) $(INC) -c -G 0 -Wa,-irix-symtab -D_ABIO32=1 -D_ABI64=3 -D_MIPS_SIM_ABI64=_ABI64 -D_MIPS_SIM_ABI32=_ABIO32 -DMIPSEB -D_LANGUAGE_ASSEMBLY -mabi=32 -fno-PIC -non_shared -mcpu=4300 -mfix4300 EGCS_ASOPTFLAGS := endif @@ -618,17 +618,24 @@ $(BUILD_DIR)/src/audio/sequence.o: CFLAGS += -use_readwrite_const ifeq ($(PLATFORM),IQUE) $(BUILD_DIR)/src/libultra/%.o: CC := $(EGCS_CC) +$(BUILD_DIR)/src/libultra/%.o: CCAS := $(EGCS_CCAS) $(BUILD_DIR)/src/libultra/%.o: CFLAGS := $(EGCS_CFLAGS) -mno-abicalls +$(BUILD_DIR)/src/libultra/%.o: CCASFLAGS := $(EGCS_CCASFLAGS) +$(BUILD_DIR)/src/libultra/%.o: ASOPTFLAGS := $(EGCS_ASOPTFLAGS) + +$(BUILD_DIR)/src/libultra/os/exceptasm.o: MIPS_VERSION := -mips3 +$(BUILD_DIR)/src/libultra/os/invaldcache.o: MIPS_VERSION := -mips3 +$(BUILD_DIR)/src/libultra/os/invalicache.o: MIPS_VERSION := -mips3 +$(BUILD_DIR)/src/libultra/os/writebackdcache.o: MIPS_VERSION := -mips3 +$(BUILD_DIR)/src/libultra/os/writebackdcacheall.o: MIPS_VERSION := -mips3 else $(BUILD_DIR)/src/libultra/%.o: CC := $(CC_OLD) -endif - $(BUILD_DIR)/src/libultra/libc/ll.o: OPTFLAGS := -O1 $(BUILD_DIR)/src/libultra/libc/ll.o: MIPS_VERSION := -mips3 -32 $(BUILD_DIR)/src/libultra/libc/llcvt.o: OPTFLAGS := -O1 $(BUILD_DIR)/src/libultra/libc/llcvt.o: MIPS_VERSION := -mips3 -32 - $(BUILD_DIR)/src/libultra/os/exceptasm.o: MIPS_VERSION := -mips3 -32 +endif $(BUILD_DIR)/src/code/%.o: ASOPTFLAGS := -O2 $(BUILD_DIR)/src/libleo/%.o: ASOPTFLAGS := -O2 diff --git a/include/ultra64/R4300.h b/include/ultra64/R4300.h index be0dfab570..1c2da84f12 100644 --- a/include/ultra64/R4300.h +++ b/include/ultra64/R4300.h @@ -4,10 +4,8 @@ #ifdef _LANGUAGE_C #include "ultratypes.h" #define U32(x) ((u32)x) -#define C_REG(x) (x) #else #define U32(x) (x) -#define C_REG(x) $x #endif /* Segment base addresses and sizes */ @@ -312,33 +310,64 @@ #define WATCHHI_VALIDMASK 0x0000000F /* Coprocessor 0 registers */ -#define C0_INX C_REG(0) -#define C0_RAND C_REG(1) -#define C0_ENTRYLO0 C_REG(2) -#define C0_ENTRYLO1 C_REG(3) -#define C0_CONTEXT C_REG(4) -#define C0_PAGEMASK C_REG(5) /* page mask */ -#define C0_WIRED C_REG(6) /* # wired entries in tlb */ -#define C0_BADVADDR C_REG(8) -#define C0_COUNT C_REG(9) /* free-running counter */ -#define C0_ENTRYHI C_REG(10) -#define C0_COMPARE C_REG(11) /* counter comparison reg. */ -#define C0_SR C_REG(12) -#define C0_CAUSE C_REG(13) -#define C0_EPC C_REG(14) -#define C0_PRID C_REG(15) /* revision identifier */ -#define C0_CONFIG C_REG(16) /* hardware configuration */ -#define C0_LLADDR C_REG(17) /* load linked address */ -#define C0_WATCHLO C_REG(18) /* watchpoint */ -#define C0_WATCHHI C_REG(19) /* watchpoint */ -#define C0_ECC C_REG(26) /* S-cache ECC and primary parity */ -#define C0_CACHE_ERR C_REG(27) /* cache error status */ -#define C0_TAGLO C_REG(28) /* cache operations */ -#define C0_TAGHI C_REG(29) /* cache operations */ -#define C0_ERROR_EPC C_REG(30) /* ECC error prg. counter */ +#ifdef _LANGUAGE_C +#define C0_INX 0 +#define C0_RAND 1 +#define C0_ENTRYLO0 2 +#define C0_ENTRYLO1 3 +#define C0_CONTEXT 4 +#define C0_PAGEMASK 5 /* page mask */ +#define C0_WIRED 6 /* # wired entries in tlb */ +#define C0_BADVADDR 8 +#define C0_COUNT 9 /* free-running counter */ +#define C0_ENTRYHI 10 +#define C0_COMPARE 11 /* counter comparison reg. */ +#define C0_SR 12 +#define C0_CAUSE 13 +#define C0_EPC 14 +#define C0_PRID 15 /* revision identifier */ +#define C0_CONFIG 16 /* hardware configuration */ +#define C0_LLADDR 17 /* load linked address */ +#define C0_WATCHLO 18 /* watchpoint */ +#define C0_WATCHHI 19 /* watchpoint */ +#define C0_ECC 26 /* S-cache ECC and primary parity */ +#define C0_CACHE_ERR 27 /* cache error status */ +#define C0_TAGLO 28 /* cache operations */ +#define C0_TAGHI 29 /* cache operations */ +#define C0_ERROR_EPC 30 /* ECC error prg. counter */ +#else +#define C0_INX $0 +#define C0_RAND $1 +#define C0_ENTRYLO0 $2 +#define C0_ENTRYLO1 $3 +#define C0_CONTEXT $4 +#define C0_PAGEMASK $5 /* page mask */ +#define C0_WIRED $6 /* # wired entries in tlb */ +#define C0_BADVADDR $8 +#define C0_COUNT $9 /* free-running counter */ +#define C0_ENTRYHI $10 +#define C0_COMPARE $11 /* counter comparison reg. */ +#define C0_SR $12 +#define C0_CAUSE $13 +#define C0_EPC $14 +#define C0_PRID $15 /* revision identifier */ +#define C0_CONFIG $16 /* hardware configuration */ +#define C0_LLADDR $17 /* load linked address */ +#define C0_WATCHLO $18 /* watchpoint */ +#define C0_WATCHHI $19 /* watchpoint */ +#define C0_ECC $26 /* S-cache ECC and primary parity */ +#define C0_CACHE_ERR $27 /* cache error status */ +#define C0_TAGLO $28 /* cache operations */ +#define C0_TAGHI $29 /* cache operations */ +#define C0_ERROR_EPC $30 /* ECC error prg. counter */ +#endif /* floating-point status register */ -#define C1_FPCSR C_REG(31) +#ifdef _LANGUAGE_C +#define C1_FPCSR 31 +#else +#define C1_FPCSR $31 +#endif #define FPCSR_FS 0x01000000 /* flush denorm to zero */ #define FPCSR_C 0x00800000 /* condition bit */ diff --git a/include/ultra64/asm.h b/include/ultra64/asm.h index acf6b8f0a7..02ef26e985 100644 --- a/include/ultra64/asm.h +++ b/include/ultra64/asm.h @@ -95,7 +95,7 @@ #define TLBP \ .set noreorder; tlbp; .set reorder -#ifdef __sgi +#ifndef __GNUC__ #define ABS(x, y) \ .globl x; \ x = y diff --git a/include/ultra64/bbskapi.h b/include/ultra64/bbskapi.h new file mode 100644 index 0000000000..7918975475 --- /dev/null +++ b/include/ultra64/bbskapi.h @@ -0,0 +1,272 @@ +/** + * @file bbskapi.h + * + * This file contains the external API for the iQue Player's Secure Kernel Calls. + * + * Applications require permission to call particular Secure Kernel Calls, defined in the associated Ticket. + * Most are not callable by games. + */ +#ifndef BB_SKAPI_H +#define BB_SKAPI_H + +#include "ultratypes.h" + +#define SKC_OK 0 +#define SKC_RECRYPT_INVALID 1 +#define SKC_RECRYPT_2 2 // Complete? +#define SKC_RECRYPT_3 3 // Partial? +#define SKC_RECRYPT_4 4 // Beginning? +#define SKC_INVALID_ARGS -1 +#define SKC_INVALID_TSRL -2 +#define SKC_INVALID_CARL -3 +#define SKC_INVALID_CPRL -4 +#define SKC_INVALID_CERT -9 +#define SKC_NO_PERMISSION -11 + +typedef struct BbAppLaunchCrls BbAppLaunchCrls; +typedef struct BbCertBase BbCertBase; +typedef struct BbEccSig BbEccSig; +typedef struct BbRecryptList BbRecryptList; +typedef struct BbShaHash BbShaHash; +typedef struct BbTicketBundle BbTicketBundle; + +/** + * Retrieves the console's unique BBID. + * + * @param bbId Location to write the BBID to. Must be a pointer to cached DRAM with 4-byte alignment. + * @return + * SKC_NO_PERMISSION If called with insufficient permission. + * SKC_INVALID_ARGS If the supplied pointer is not valid. + * SKC_OK Otherwise. + */ +s32 skGetId(u32* bbId); + +/** + * Prepares to launch an application. + * The provided ticket bundle is verified and made the active ticket bundle. + * The AES decryption hardware is prepared. + * + * @param bundle Ticket Bundle associated with this application. + * @param crls Application Certificate Revocation Lists to check when verifying the ticket bundle. + * The ticket bundle must be signed by the Root signature without going through any + * revoked certificates. + * @param recryptList System Recrypt List (encrypted and digitally signed) + * @return + * SKC_INVALID_ARGS If any inputs are or contain invalid pointers, + * or the ticket is not for this console, + * or the ticket is for a trial that has expired. + * SKC_INVALID_TSRL If the provided TSRL revocation list is invalid. + * SKC_INVALID_CARL If the provided CARL revocation list is invalid. + * SKC_INVALID_CPRL If the provided CPRL revocation list is invalid. + * SKC_INVALID_CERT If a digital certificate was revoked by one of the revocation lists. + * SKC_RECRYPT_3 If the recrypt state for this app is not in an acceptable state to be launched. + * SKC_RECRYPT_4 If the recrypt state for this app is not in an acceptable state to be launched. + * SKC_NO_PERMISSION If called with insufficient permission. + * SKC_OK Otherwise. + */ +s32 skLaunchSetup(BbTicketBundle* bundle, BbAppLaunchCrls* crls, BbRecryptList* recryptList); + +/** + * Launches a prepared application that is assumed to have been loaded into memory at the entrypoint between calling + * skLaunchSetup and calling this. skLaunchSetup must have been called prior to set the active ticket bundle. + * + * @param entrypoint The entrypoint address of the app to launch. + * + * @return + * SKC_INVALID_ARGS If the entrypoint is an invalid pointer, + * or if content failed a hash check for non-recrypted apps, + * or if the content is an expired trial. + * SKC_NO_PERMISSION If called with insufficient permission. + * @note Does not return if the call is successful. + */ +s32 skLaunch(void* entrypoint); + +/** + * Verifies whether a provided Recrypt List is valid. + * + * @param recryptList Pointer to the (encrypted and digitally signed) recrypt list to verify. + * @return + * SKC_OK If the recrypt list is valid + * SKC_INVALID_ARGS If the recrypt list is invalid + * (e.g. contains invalid pointers or its ECDSA signature fails to verify) + * SKC_NO_PERMISSION If called with insufficient permission. + */ +s32 skRecryptListValid(BbRecryptList* recryptList); + +/** + * Begins a new recryption task. Content downloaded is initially encrypted with the Common Key but may be re-encrypted + * with a new randomly generated AES key if the recrypt flag is set in the content metadata. Like with skLaunchSetup, + * the provided ticket bundle is first verified before being made the active ticket bundle. + * + * @param bundle The ticket bundle associated with the content that will be recrypted. + * @param crls Application Certificate Revocation Lists to check when verifying the ticket bundle. + * The ticket bundle must be signed by the Root signature without going through any + * revoked certificates. + * @param recryptList The recrypt list that the AES key will be saved to, after being encrypted with the + * console-specific recrypt list key. + * @return + * SKC_RECRYPT_INVALID If called on a ticket bundle that does not have the recrypt flag set. + * SKC_INVALID_ARGS If any inputs are or contain invalid pointers, + * or the ticket is not for this console, + * or the ticket is for a trial that has expired. + * SKC_INVALID_TSRL If the provided TSRL revocation list is invalid. + * SKC_INVALID_CARL If the provided CARL revocation list is invalid. + * SKC_INVALID_CPRL If the provided CPRL revocation list is invalid. + * SKC_INVALID_CERT If a digital certificate was revoked by one of the revocation lists. + * SKC_NO_PERMISSION If called with insufficient permission. + * Otherwise, one of SKC_RECRYPT_* will be returned communicating the initial state of the recryption process. + */ +s32 skRecryptBegin(BbTicketBundle* bundle, BbAppLaunchCrls* crls, BbRecryptList* recryptList); + +/** + * Recrypts the provided data, using the previously set context. + * Must be called following skRecryptBegin. + * + * @param buf Pointer to app content to encrypt and hash. + * @param size Amount of data to process in this buffer. + * @return + * SKC_INVALID_ARGS If the provided buffer is not fully contained in RAM or is otherwise invalid. + * SKC_NO_PERMISSION If called with insufficient permission. + * SKC_OK Otherwise. + */ +s32 skRecryptData(u8* buf, u32 size); + +/** + * Resumes a partially-complete recryption. The last chunk of successfully-recrypted data must be provided in order to + * set the AES-128-CBC Initialization Vector to continue recryption of the next chunk. + * Must be called following skRecryptBegin. + * + * @param buf Pointer to last chunk of successfully-recrypted content. + * @param size Amount of data available. + * @return + * SKC_INVALID_ARGS If the provided buffer is not fully contained in RAM or is otherwise invalid. + * SKC_NO_PERMISSION If called with insufficient permission. + * SKC_OK Otherwise. + */ +s32 skRecryptComputeState(u8* buf, u32 size); + +/** + * Concludes the recryption process. The SHA-1 hash of the content, computed during recryption, is checked against the + * hash in the active ticket bundle; if it passes, the recrypt list entry for the active content is updated to indicate + * that recryption is complete and was successful. + * + * @param recryptList The (encrypted and digitally signed) recrypt list to update. + * @return + * SKC_OK If recryption succeeded. + * SKC_INVALID_ARGS If recryption failed (e.g. if the hash of the content did not match the hash in the ticket bundle) + * or if the provided recrypt list is invalid or cannot find the entry for the content. + * SKC_NO_PERMISSION If called with insufficient permission. + */ +s32 skRecryptEnd(BbRecryptList* recryptList); + +/** + * Generates a digital signature for the provided SHA-1 hash (treated as a message) using the Elliptic Curve Digital + * Signature Algorithm (ECDSA) on the curve sect233r1 with the console's ECDSA Private Key. Appends an identity of 1 to + * the end of the message prior to signing. + * + * @param hash The SHA-1 hash to sign. + * @param outSignature The resulting ECDSA digital signature. + * @return + * SKC_INVALID_ARGS If either of the arguments is an invalid pointer. + * SKC_NO_PERMISSION If called with insufficient permission. + * SKC_OK Otherwise. + */ +s32 skSignHash(BbShaHash* hash, BbEccSig* outSignature); + +/** + * Verifies a SHA-1 hash (treated as a message) against a digital signature using either the Elliptic Curve Digital + * Signature Algorithm (ECDSA) or the RSA Digital Signature Algorithm. For RSA, either 2048-bit or 4096-bit signatures + * can be recognized. + * + * For verifying self-signed (e.g. via skSignHash) ECDSA signatures the certificate chain and revocation lists are not + * required and may be passed as NULL, the public key is the console's own ECDSA public key. For verifying other types + * of signatures, a valid certificate chain and certificate revocation lists must be provided, in which case the + * signature must be signed by the Root certificate without going through any revoked certificates. + * + * This can only verify hashes signed with an identity of 1, such as those signed via skSignHash. + * + * @param hash The SHA-1 hash to check the signature of. + * @param signature The signature to compare against. May be an ECDSA, RSA2048 or RSA4096 signature. + * @param certChain Certificate Chain, NULL-terminated list of certificate pointers. + * Not required for self-signed ECDSA signatures and must be NULL in that case. + * Should not be more than 5 certificates long. + * Should end on the Root signature. + * @param crls Certificate Revocation Lists to check certificates against. Not required for self-signed ECDSA signatures. + * @return + * SKC_OK If the hash was successfully verified against the signature. + * SKC_INVALID_ARGS If any arguments are invalid pointers, + * or the hash could not be verified against the digital signature, + * or the certificate chain was invalid, + * or if any certificate revocation lists were invalid. + * SKC_INVALID_CERT If a digital certificate was revoked by one of the revocation lists. + * SKC_NO_PERMISSION If called with insufficient permission. + */ +s32 skVerifyHash(BbShaHash* hash, u32* signature, BbCertBase** certChain, BbAppLaunchCrls* crls); + +/** + * Retrieves the consumption counters for all currently-tracked applications and the Ticket ID (TID) Window. + * + * The TID Window determines the TID for the first counter (cc[0]), the other counters (cc[i]) are associated with + * tidWindow + i. + * + * The consumption counters track either the number of minutes that a trial app has been played for, or the number of + * times a trial app has been launched. + * + * @param tidWindow The location to save the TID window to. + * @param cc An array of 26 u16s to save the consumption counters into. + * @return + * SKC_INVALID_ARGS If either pointer is invalid or there is not enough room to save all the consumption counters. + * SKC_NO_PERMISSION If called with insufficient permission. + * SKC_OK Otherwise. + */ +s32 skGetConsumption(u16* tidWindow, u16 cc[26]); + +/** + * Increments the Ticket ID Window by 1 and moves all consumption counters down by 1 slot to match the new window. The + * counter previously at position 0 is forgotten. + * + * @return + * SKC_NO_PERMISSION If called with insufficient permission. + * SKC_INVALID_ARGS If the resulting state could not be saved internally. + * SKC_OK If success. + */ +s32 skAdvanceTicketWindow(void); + +/** + * Overrides the trial limit and trial type stored in the currently loaded ticket. + * + * @param limit The new trial limit. Either a length of time or the number of allowed launches, depending on trial type. + * @param code The new trial type + * 0 = Time-limited in minutes, call skKeepAlive periodically + * 1 = Limited by number of launches + * 2 = Time-limited in minutes, no need to call skKeepAlive (TOVERIFY) + * @return + * SKC_OK If success. + * SKC_INVALID_ARGS If no ticket is currently loaded. + * SKC_NO_PERMISSION If called with insufficient permission. + */ +s32 skSetLimit(u16 limit, u16 code); + +/** + * Returns to the system menu. + * + * @return + * SKC_NO_PERMISSION If called with insufficient permission. + * @note Does not return if called with permission. + */ +s32 skExit(void); + +/** + * Keeps trial applications alive. + * + * The hardware trial timer does not have a very long period so must be refreshed periodically by calling this function. + * This function updates the timer and checks for an expiry. + * + * @return + * SKC_NO_PERMISSION If called with insufficient permission. + * SKC_OK Otherwise. + * @note This function may not return if it detects the trial has expired. + */ +s32 skKeepAlive(void); + +#endif diff --git a/include/ultra64/bcp.h b/include/ultra64/bcp.h new file mode 100644 index 0000000000..7b139b3de0 --- /dev/null +++ b/include/ultra64/bcp.h @@ -0,0 +1,29 @@ +#ifndef BCP_H +#define BCP_H + +#include "rcp.h" + +/****************************************************************************** + * Additional MIPS Interface (MI) Registers + */ + +/** + * Accesses to this register outside of Secure Mode cause an NMI to transfer control + * to the Secure Kernel. + * + * [25] ?: System software writes to this bit when launching an app or game + * [24] SK RAM Access: Set to 1 to enable access to 0x8000 bytes at 0x1FC40000 + * [7] Secure Trap Cause: Memory card removed + * [6] Secure Trap Cause: Power button pressed + * [5] Secure Trap Cause: MI Error + * [4] Secure Trap Cause: PI Error + * [3] Secure Trap Cause: Timer expired + * [2] Secure Trap Cause: Syscall via read of this register outside of secure mode + * [1] Boot ROM Swap: 0 = SK mapped at 0x1FC00000, Boot ROM mapped at 0x1FC20000 + * 1 = Boot ROM mapped at 0x1FC00000, SK mapped at 0x1FC20000 + * [0] Secure Mode: 0 = not in secure mode + * 1 = in secure mode + */ +#define MI_SECURE_EXCEPTION_REG (MI_BASE_REG + 0x14) + +#endif diff --git a/src/libultra/bb/sk/skapi.s b/src/libultra/bb/sk/skapi.s index e69de29bb2..3e80adfcd1 100644 --- a/src/libultra/bb/sk/skapi.s +++ b/src/libultra/bb/sk/skapi.s @@ -0,0 +1,48 @@ +#ifdef BBPLAYER +#include "ultra64/asm.h" +#include "ultra64/regdef.h" +#include "ultra64/bcp.h" + +.text + +#define SKC(name, num) \ + LEAF(name) ;\ + .set noreorder ;\ + /* Load syscall number into v0 */ ;\ + li v0, num ;\ + /* Read from MI_SECURE_EXCEPTION_REG to */ ;\ + /* transfer control to the Secure Kernel */ ;\ + li t0, PHYS_TO_K1(MI_SECURE_EXCEPTION_REG) ;\ + lw t1, (t0) ;\ + nop ;\ + jr ra ;\ + nop ;\ + .set reorder ;\ + END(name) + +SKC(skGetId, 0) +SKC(skLaunchSetup, 1) +SKC(skLaunch, 2) +SKC(skRecryptListValid, 3) +SKC(skRecryptBegin, 4) +SKC(skRecryptData, 5) +SKC(skRecryptComputeState, 6) +SKC(skRecryptEnd, 7) +SKC(skSignHash, 8) +SKC(skVerifyHash, 9) +SKC(skGetConsumption, 10) +SKC(skAdvanceTicketWindow, 11) +SKC(skSetLimit, 12) +SKC(skExit, 13) +SKC(skKeepAlive, 14) + +/* These are not valid for a retail Secure Kernel, their usage pattern is unknown. */ + +SKC(skGetRandomKeyData, 15) +SKC(skDumpVirage, 16) +SKC(skTest2, 17) +SKC(skTest3, 18) +SKC(skResetWindow, 19) +SKC(skValidateRls, 20) + +#endif diff --git a/src/libultra/os/parameters.s b/src/libultra/os/parameters.s index b881148144..179dbcf02f 100644 --- a/src/libultra/os/parameters.s +++ b/src/libultra/os/parameters.s @@ -23,7 +23,4 @@ IPL_SYMBOL(osVersion, 0x80000314, 4) IPL_SYMBOL(osMemSize, 0x80000318, 4) IPL_SYMBOL(osAppNMIBuffer, 0x8000031C, 0x40) - -.repeat 0x60/4 - NOP -.endr +.space 0x60 diff --git a/src/makerom/entry.s b/src/makerom/entry.s index e6074357b0..870b979d69 100644 --- a/src/makerom/entry.s +++ b/src/makerom/entry.s @@ -52,10 +52,8 @@ END(entrypoint) #ifdef __sgi /* IDO can't take absolute differences of symbols so the size of the above is hardcoded */ -.repeat (0x60 - 0x34) - .byte 0 -.endr +.space PAD_TO - 0x34 #else /* Pad to a total size taking into account the size of the above */ -.fill PAD_TO - (. - entrypoint) +.space PAD_TO - (. - entrypoint) #endif