diff --git a/include/arm11/hardware/spi.h b/include/arm11/hardware/spi.h index aa3306a..a945909 100644 --- a/include/arm11/hardware/spi.h +++ b/include/arm11/hardware/spi.h @@ -75,17 +75,14 @@ void NSPI_init(void); /** - * @brief Automatically polls a bit of the command response. + * @brief Automatically polls a bit of the command response. Use with the macro below. * - * @param[in] dev The device ID. See table above. - * @param[in] cmd The command. - * @param[in] timeout The timeout. Must be 0-15. Tries = 31<I2C_CNT & I2C_ENABLE) __wfi(); + do + { + __wfi(); + } while(regs->I2C_CNT & I2C_ENABLE); +} + +static bool i2cCheckAck(I2cRegs *const regs) +{ + if(!(regs->I2C_CNT & I2C_ACK)) // If ack flag is 0 it failed. + { + regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_ERROR | I2C_STOP; + return false; + } + + return true; } void I2C_init(void) @@ -136,21 +150,13 @@ regs->I2C_DATA = devAddr; regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_DIRE_WRITE | I2C_START; i2cWaitBusyIrq(regs); - if(!(regs->I2C_CNT & I2C_ACK)) // If ack flag is 0 it failed. - { - regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_ERROR | I2C_STOP; - continue; - } + if(!i2cCheckAck(regs)) continue; // Select register. regs->I2C_DATA = regAddr; regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_DIRE_WRITE; i2cWaitBusyIrq(regs); - if(!(regs->I2C_CNT & I2C_ACK)) - { - regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_ERROR | I2C_STOP; - continue; - } + if(!i2cCheckAck(regs)) continue; // Select device in read mode for read transfer. if(read) @@ -158,11 +164,7 @@ regs->I2C_DATA = devAddr | 1u; // Set bit 0 for read. regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_DIRE_WRITE | I2C_START; i2cWaitBusyIrq(regs); - if(!(regs->I2C_CNT & I2C_ACK)) - { - regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_ERROR | I2C_STOP; - continue; - } + if(!i2cCheckAck(regs)) continue; } break; @@ -207,22 +209,14 @@ regs->I2C_DATA = *in++; regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_DIRE_WRITE; i2cWaitBusyIrq(regs); - if(!(regs->I2C_CNT & I2C_ACK)) - { - regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_ERROR | I2C_STOP; - return false; - } + if(!i2cCheckAck(regs)) return false; } // Last byte transfer. regs->I2C_DATA = *in; regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_DIRE_WRITE | I2C_STOP; i2cWaitBusyIrq(regs); - if(!(regs->I2C_CNT & I2C_ACK)) - { - regs->I2C_CNT = I2C_ENABLE | I2C_IRQ_ENABLE | I2C_ERROR | I2C_STOP; - return false; - } + if(!i2cCheckAck(regs)) return false; return true; } @@ -254,21 +248,13 @@ regs->I2C_DATA = devAddr; regs->I2C_CNT = I2C_ENABLE | I2C_DIRE_WRITE | I2C_START; while(regs->I2C_CNT & I2C_ENABLE); - if(!(regs->I2C_CNT & I2C_ACK)) // If ack flag is 0 it failed. - { - regs->I2C_CNT = I2C_ENABLE | I2C_ERROR | I2C_STOP; - continue; - } + if(!i2cCheckAck(regs)) continue; // Select register. regs->I2C_DATA = regAddr; regs->I2C_CNT = I2C_ENABLE | I2C_DIRE_WRITE; while(regs->I2C_CNT & I2C_ENABLE); - if(!(regs->I2C_CNT & I2C_ACK)) - { - regs->I2C_CNT = I2C_ENABLE | I2C_ERROR | I2C_STOP; - continue; - } + if(!i2cCheckAck(regs)) continue; break; } while(--tries > 0); @@ -278,11 +264,7 @@ regs->I2C_DATA = data; regs->I2C_CNT = I2C_ENABLE | I2C_DIRE_WRITE | I2C_STOP; while(regs->I2C_CNT & I2C_ENABLE); - if(!(regs->I2C_CNT & I2C_ACK)) - { - regs->I2C_CNT = I2C_ENABLE | I2C_ERROR | I2C_STOP; - return false; - } + if(!i2cCheckAck(regs)) return false; return true; } diff --git a/source/arm11/hardware/interrupt.c b/source/arm11/hardware/interrupt.c index b933cd4..717fc76 100644 --- a/source/arm11/hardware/interrupt.c +++ b/source/arm11/hardware/interrupt.c @@ -64,6 +64,8 @@ } else // Other core. Same as above but for core specific IRQs. { + REGs_GID_ENA_CLR[0] = 0xFFFFFFFFu; + REGs_GID_PEN_CLR[0] = 0xFFFFFFFFu; for(u32 i = 0; i < 8; i++) REGs_GID_IPRIO[i] = 0xE0E0E0E0u; diff --git a/source/arm11/hardware/spi.c b/source/arm11/hardware/spi.c index fb046de..b83c2b1 100644 --- a/source/arm11/hardware/spi.c +++ b/source/arm11/hardware/spi.c @@ -54,12 +54,12 @@ } spiDevTable[] = { {SPI_BUS3, 0u<<6 | NSPI_CLK_512KHz}, - {SPI_BUS3, 1u<<6 | 0}, // TODO: Baudrate - {SPI_BUS3, 2u<<6 | 0}, // TODO: Baudrate + {SPI_BUS3, 1u<<6 | 0}, // TODO: Clock + {SPI_BUS3, 2u<<6 | 0}, // TODO: Clock {SPI_BUS1, 0u<<6 | NSPI_CLK_4MHz}, - {SPI_BUS1, 1u<<6 | 0}, // TODO: Baudrate - {SPI_BUS1, 2u<<6 | 0}, // TODO: Baudrate - {SPI_BUS2, 0u<<6 | 0} // TODO: Baudrate + {SPI_BUS1, 1u<<6 | 0}, // TODO: Clock + {SPI_BUS1, 2u<<6 | 0}, // TODO: Clock + {SPI_BUS2, 0u<<6 | 0} // TODO: Clock }; @@ -121,11 +121,11 @@ regs->NSPI_INT_STAT = NSPI_INT_AP_TIMEOUT | NSPI_INT_AP_SUCCESS | NSPI_INT_UNK; } -bool NSPI_autoPollBit(SpiDevice dev, u8 cmd, u8 timeout, u8 off, bool bitSet) +bool _NSPI_autoPollBit(SpiDevice dev, u32 params) { SpiRegs *const regs = nspiGetBusRegsBase(spiDevTable[dev].busId); - regs->NSPI_AUTOPOLL = NSPI_AUTOPOLL_START | bitSet<<30 | off<<24 | timeout<<16 | cmd; + regs->NSPI_AUTOPOLL = NSPI_AUTOPOLL_START | params; u32 res; do diff --git a/source/arm11/hardware/timer.c b/source/arm11/hardware/timer.c index 37a2343..86967ef 100644 --- a/source/arm11/hardware/timer.c +++ b/source/arm11/hardware/timer.c @@ -67,7 +67,10 @@ REG_TIMER_LOAD = ticks; REG_TIMER_CNT = TIMER_IRQ_ENABLE | TIMER_SINGLE_SHOT | TIMER_ENABLE; - while(REG_TIMER_COUNTER) __wfe(); + do + { + __wfi(); + } while(REG_TIMER_COUNTER); // Checking the REG_TIMER_CNT enable bit is broken. REG_TIMER_INT_STAT = 1; } diff --git a/source/arm9/hardware/cache.s b/source/arm9/hardware/cache.s index 4bd717d..19b81ff 100644 --- a/source/arm9/hardware/cache.s +++ b/source/arm9/hardware/cache.s @@ -52,8 +52,8 @@ mov r0, #0 flushDCache_inner_lp: orr r2, r1, r0 @ Generate segment and line address - mcr p15, 0, r2, c7, c10, 2 @ "Clean data cache entry Index and segment" add r0, r0, #CACHE_LINE_SIZE + mcr p15, 0, r2, c7, c10, 2 @ "Clean data cache entry Index and segment" cmp r0, #(DCACHE_SIZE / 4) bne flushDCache_inner_lp add r1, r1, #0x40000000 @@ -69,8 +69,8 @@ mov r0, #0 flushInvalidateDCache_inner_lp: orr r2, r1, r0 @ Generate segment and line address - mcr p15, 0, r2, c7, c14, 2 @ "Clean and flush data cache entry Index and segment" add r0, r0, #CACHE_LINE_SIZE + mcr p15, 0, r2, c7, c14, 2 @ "Clean and flush data cache entry Index and segment" cmp r0, #(DCACHE_SIZE / 4) bne flushInvalidateDCache_inner_lp add r1, r1, #0x40000000 @@ -85,13 +85,13 @@ bhi flushDCache add r1, r1, r0 bic r0, r0, #(CACHE_LINE_SIZE - 1) + mov r2, #0 flushDCacheRange_lp: mcr p15, 0, r0, c7, c10, 1 @ "Clean data cache entry Address" add r0, r0, #CACHE_LINE_SIZE cmp r0, r1 blt flushDCacheRange_lp - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer + mcr p15, 0, r2, c7, c10, 4 @ Drain write buffer bx lr @@ -100,13 +100,13 @@ bhi flushInvalidateDCache add r1, r1, r0 bic r0, r0, #(CACHE_LINE_SIZE - 1) + mov r2, #0 flushInvalidateDCacheRange_lp: mcr p15, 0, r0, c7, c14, 1 @ "Clean and flush data cache entry Address" add r0, r0, #CACHE_LINE_SIZE cmp r0, r1 blt flushInvalidateDCacheRange_lp - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer + mcr p15, 0, r2, c7, c10, 4 @ Drain write buffer bx lr @@ -125,13 +125,13 @@ tst r1, #(CACHE_LINE_SIZE - 1) mcrne p15, 0, r1, c7, c10, 1 @ "Clean data cache entry Address" bic r0, r0, #(CACHE_LINE_SIZE - 1) + mov r2, #0 invalidateDCacheRange_lp: mcr p15, 0, r0, c7, c6, 1 @ "Flush data cache single entry Address" add r0, r0, #CACHE_LINE_SIZE cmp r0, r1 blt invalidateDCacheRange_lp - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer + mcr p15, 0, r2, c7, c10, 4 @ Drain write buffer bx lr diff --git a/source/arm9/hardware/crypto.c b/source/arm9/hardware/crypto.c index 67fdfc6..54ac76c 100644 --- a/source/arm9/hardware/crypto.c +++ b/source/arm9/hardware/crypto.c @@ -308,7 +308,7 @@ static void aesProcessBlocksCpu(const u32 *in, u32 *out, u32 blocks) { REG_AES_BLKCNT_HIGH = blocks; - REG_AESCNT |= AES_ENABLE | 3<<12 | AES_FLUSH_READ_FIFO | AES_FLUSH_WRITE_FIFO; + REG_AESCNT |= AES_ENABLE | 3u<<12 | AES_FLUSH_READ_FIFO | AES_FLUSH_WRITE_FIFO; for(u32 i = 0; i < blocks * 4; i += 4) { @@ -354,7 +354,10 @@ REG_AES_BLKCNT_HIGH = blocks; REG_AESCNT |= AES_ENABLE | AES_IRQ_ENABLE | aesFifoSize<<14 | (3 - aesFifoSize)<<12 | AES_FLUSH_READ_FIFO | AES_FLUSH_WRITE_FIFO; - while(REG_AESCNT & AES_ENABLE) __wfi(); + do + { + __wfi(); + } while(REG_AESCNT & AES_ENABLE); } void AES_ctr(AES_ctx *const ctx, const u32 *in, u32 *out, u32 blocks, bool dma) @@ -676,7 +679,7 @@ fb_assert(encSig != NULL); const u8 keyslot = RSA_GET_KEYSLOT; - rsaWaitBusy(); + rsaWaitBusy(); // TODO: IRQs? if(!(rsaSlots[keyslot].REG_RSA_SLOTCNT & RSA_KEY_STAT_SET)) return false; REG_RSA_CNT |= RSA_INPUT_NORMAL | RSA_INPUT_BIG; @@ -697,32 +700,20 @@ alignas(4) u8 decSig[0x100]; if(!RSA_decrypt2048((u32*)decSig, encSig)) return false; - if(decSig[0] != 0x00 || decSig[1] != 0x01) return false; - + if(*((u16*)decSig) != 0x0100u) return false; u32 read = 2; - while(read < 0x100) - { - if(decSig[read] != 0xFF) break; - read++; - } + while(decSig[read] == 0xFF && ++read < 0x100); if(read != 0xCC || decSig[read] != 0x00) return false; // ASN.1 is a clusterfuck so we skip parsing the remaining headers // and hardcode the hash location. - alignas(4) u8 hash[32]; - sha(data, size, (u32*)hash, SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG); + u32 calcHash[8]; + sha(data, size, calcHash, SHA_INPUT_BIG | SHA_MODE_256, SHA_OUTPUT_BIG); // Compare hash - u8 res = 0; - for(u32 i = 0; i < 32; i++) - { - u8 tmp; - if(decSig[0xE0 + i] == hash[i]) tmp = 0; - else tmp = 1; - - res |= tmp; - } + u32 res = 0; + for(u32 i = 0; i < 8; i++) res |= ((u32*)(decSig + 0xE0))[i] ^ calcHash[i]; return res == 0; } diff --git a/source/arm9/hardware/ndma.c b/source/arm9/hardware/ndma.c index 4014c39..c70e51a 100644 --- a/source/arm9/hardware/ndma.c +++ b/source/arm9/hardware/ndma.c @@ -53,7 +53,10 @@ { NDMA_copyAsync(dest, source, size); - while(REG_NDMA7_CNT & NDMA_ENABLE) __wfi(); + do + { + __wfi(); + } while(REG_NDMA7_CNT & NDMA_ENABLE); } void NDMA_fillAsync(u32 *dest, u32 value, u32 size) @@ -72,5 +75,8 @@ { NDMA_fillAsync(dest, value, size); - while(REG_NDMA7_CNT & NDMA_ENABLE) __wfi(); + do + { + __wfi(); + } while(REG_NDMA7_CNT & NDMA_ENABLE); } diff --git a/source/arm9/hardware/spicard.c b/source/arm9/hardware/spicard.c index 0e0fc01..a3ed321 100644 --- a/source/arm9/hardware/spicard.c +++ b/source/arm9/hardware/spicard.c @@ -89,9 +89,9 @@ REG_NSPI_INT_STAT = NSPI_INT_AP_TIMEOUT | NSPI_INT_AP_SUCCESS | NSPI_INT_UNK; // Aknowledge } -bool SPICARD_autoPollBit(u8 cmd, u8 timeout, u8 off, bool bitSet) +bool _SPICARD_autoPollBit(u32 params) { - REG_NSPI_AUTOPOLL = NSPI_AUTOPOLL_START | bitSet<<30 | off<<24 | timeout<<16 | cmd; + REG_NSPI_AUTOPOLL = NSPI_AUTOPOLL_START | params; u32 res; do diff --git a/source/arm9/hardware/timer.c b/source/arm9/hardware/timer.c index 0fa7ff8..09f957f 100644 --- a/source/arm9/hardware/timer.c +++ b/source/arm9/hardware/timer.c @@ -84,7 +84,10 @@ REG_TIMER3_CNT = TIMER_ENABLE | TIMER_IRQ_ENABLE | TIMER_PRESCALER_64; - while(REG_TIMER3_CNT & TIMER_ENABLE) __wfi(); + do + { + __wfi(); + } while(REG_TIMER3_CNT & TIMER_ENABLE); } static void timerSleepHandler(UNUSED u32 id)