- unified CPU/cache header that works on C and asm code

- added legacy boot PXI command that allows power savings on ARM11
This commit is contained in:
Wolfvak 2019-04-09 09:33:52 -03:00 committed by d0k3
parent 987b820c4a
commit e70b8ab116
14 changed files with 459 additions and 344 deletions

View File

@ -1,9 +1,6 @@
#include <types.h>
#include <cpu.h>
#include <gic.h>
#include <string.h>
#define IRQVECTOR_BASE ((vu32*)0x1FFFFFA0)
extern void (*main_irq_handler)(void);
@ -14,7 +11,8 @@ void GIC_Reset(void)
u32 irq_s;
REG_GIC_CONTROL = 0;
memset(GIC_Handlers, 0, sizeof(GIC_Handlers));
for (int i = 0; i < 128; i++)
GIC_Handlers[i] = NULL;
REG_DIC_CONTROL = 0;
for (int i = 0; i < 4; i++) {

View File

@ -11,8 +11,8 @@
.type main_irq_handler, %function
main_irq_handler:
sub lr, lr, #4 @ Fix return address
srsfd sp!, #0x13 @ Store IRQ mode LR and SPSR on the SVC stack
cps #0x13 @ Switch to SVC mode
srsfd sp!, #SR_SVC_MODE @ Store IRQ mode LR and SPSR on the SVC stack
cps #SR_SVC_MODE @ Switch to SVC mode
push {r0-r3, r12, lr} @ Preserve registers
1:

View File

@ -1,4 +1,4 @@
#include <cpu.h>
#include <arm.h>
#include <pxi.h>
#include <gic.h>
#include <gpulcd.h>
@ -10,15 +10,25 @@
#define CFG11_MPCORE_CLKCNT ((vu16*)(0x10141300))
#define CFG11_SOCINFO ((vu16*)(0x10140FFC))
vu32 *entrypoint = (vu32*)0x1FFFFFFC;
#define LEGACY_BOOT_ENTRY ((vu32*)0x1FFFFFFC)
#define LEGACY_BOOT_MAGIC (0xDEADDEAD)
void PXI_RX_Handler(void)
{
u32 pxi_cmd, ret;
u32 pxi_args[PXI_FIFO_LEN];
u32 ret, msg, cmd, argc, args[PXI_FIFO_LEN];
pxi_cmd = PXI_Recv();
switch (pxi_cmd) {
msg = PXI_Recv();
cmd = msg & 0xFFFF;
argc = msg >> 16;
if (argc > PXI_FIFO_LEN) {
PXI_Send(0xFFFFFFFF);
return;
}
PXI_RecvArray(args, argc);
switch (cmd) {
case PXI_SCREENINIT:
{
GPU_Init();
@ -35,26 +45,28 @@ void PXI_RX_Handler(void)
case PXI_BRIGHTNESS:
{
PXI_RecvArray(pxi_args, 1);
LCD_SetBrightness(0, pxi_args[0]);
LCD_SetBrightness(1, pxi_args[0]);
ret = pxi_args[0];
LCD_SetBrightness(0, args[0]);
LCD_SetBrightness(1, args[0]);
ret = args[0];
break;
}
case PXI_I2C_READ:
{
PXI_RecvArray(pxi_args, 4);
ret = I2C_readRegBuf(pxi_args[0], pxi_args[1],
(u8*)pxi_args[2], pxi_args[3]);
ret = I2C_readRegBuf(args[0], args[1], (u8*)args[2], args[3]);
break;
}
case PXI_I2C_WRITE:
{
PXI_RecvArray(pxi_args, 4);
ret = I2C_writeRegBuf(pxi_args[0], pxi_args[1],
(const u8*)pxi_args[2], pxi_args[3]);
ret = I2C_writeRegBuf(args[0], args[1], (u8*)args[2], args[3]);
break;
}
case PXI_LEGACY_BOOT:
{
*LEGACY_BOOT_ENTRY = LEGACY_BOOT_MAGIC;
ret = 0;
break;
}
@ -62,7 +74,6 @@ void PXI_RX_Handler(void)
case CMD_ID:
{
<var declarations/assignments>
<receive args from PXI FIFO>
<execute the command>
<set the return value>
break;
@ -85,12 +96,12 @@ void main(void)
if ((*CFG11_SOCINFO & 2) && (!(*CFG11_MPCORE_CLKCNT & 1))) {
GIC_Reset();
GIC_SetIRQ(88, NULL);
CPU_EnableIRQ();
arm_enable_ints();
*CFG11_MPCORE_CLKCNT = 0x8001;
do {
asm("wfi\n\t");
} while(!(*CFG11_MPCORE_CLKCNT & 0x8000));
CPU_DisableIRQ();
arm_disable_ints();
}
GIC_Reset();
@ -100,14 +111,20 @@ void main(void)
//MCU_init();
GIC_SetIRQ(IRQ_PXI_RX, PXI_RX_Handler);
*LEGACY_BOOT_ENTRY = 0;
CPU_EnableIRQ();
arm_enable_ints();
*entrypoint = 0;
while((entry=*entrypoint) == 0);
do {
arm_wfi();
} while(*LEGACY_BOOT_ENTRY != LEGACY_BOOT_MAGIC);
CPU_DisableIRQ();
arm_disable_ints();
GIC_Reset();
do {
entry = *LEGACY_BOOT_ENTRY;
} while(entry == LEGACY_BOOT_MAGIC);
((void (*)())(entry))();
}

View File

@ -1,6 +1,6 @@
#include "arm.h"
#include "power.h"
#include "i2c.h"
#include "cache.h"
#include "pxi.h"
static const u8 br_settings[] = {0x10, 0x17, 0x1E, 0x25, 0x2C, 0x34, 0x3C, 0x44, 0x4D, 0x56, 0x60, 0x6B, 0x79, 0x8C, 0xA7, 0xD2};
@ -35,8 +35,8 @@ bool IsCharging() {
void Reboot() {
I2C_writeReg(I2C_DEV_MCU, 0x22, 1 << 0); // poweroff LCD to prevent MCU hangs
cpu_writeback_dc();
cpu_membarrier();
arm_wb_dc();
arm_dsb();
I2C_writeReg(I2C_DEV_MCU, 0x20, 1 << 2);
while(true);
}
@ -44,8 +44,8 @@ void Reboot() {
void PowerOff()
{
I2C_writeReg(I2C_DEV_MCU, 0x22, 1 << 0); // poweroff LCD to prevent MCU hangs
cpu_writeback_dc();
cpu_membarrier();
arm_wb_dc();
arm_dsb();
I2C_writeReg(I2C_DEV_MCU, 0x20, 1 << 0);
while(true);
}

View File

@ -19,6 +19,7 @@
#include "power.h"
#include "vram0.h"
#include "i2c.h"
#include "pxi.h"
#ifndef N_PANES
#define N_PANES 3
@ -99,6 +100,7 @@ u32 BootFirmHandler(const char* bootpath, bool verbose, bool delete) {
// boot the FIRM (if we got a proper fixpath)
if (*fixpath) {
if (delete) PathDelete(bootpath);
PXI_DoCMD(PXI_LEGACY_BOOT, NULL, 0);
BootFirm((FirmHeader*) firm, fixpath);
while(1);
}

View File

@ -10,9 +10,7 @@
.global _start
_start:
@ Disable interrupts
mrs r4, cpsr
orr r4, r4, #(SR_IRQ | SR_FIQ)
msr cpsr_c, r4
msr cpsr_c, #(SR_SVC_MODE | SR_NOINT)
@ Preserve boot registers
mov r8, r0
@ -35,9 +33,8 @@ _start:
blx r0 @ Invalidate Instruction Cache
@ Disable caches / DTCM / MPU
ldr r1, =(CR_ENABLE_MPU | CR_ENABLE_DCACHE | CR_ENABLE_ICACHE | \
CR_ENABLE_DTCM)
ldr r2, =(CR_ENABLE_ITCM)
ldr r1, =(CR_MPU | CR_DCACHE | CR_ICACHE | CR_DTCM | CR_TCM_LOAD)
ldr r2, =(CR_ITCM)
mrc p15, 0, r0, c1, c0, 0
bic r0, r1
orr r0, r2
@ -94,16 +91,15 @@ _start:
blo .LXRQ_Install
@ Enable caches / DTCM / select low exception vectors
ldr r1, =(CR_ALT_VECTORS | CR_DISABLE_TBIT)
ldr r2, =(CR_ENABLE_MPU | CR_ENABLE_DCACHE | CR_ENABLE_ICACHE | \
CR_ENABLE_DTCM | CR_CACHE_RROBIN)
ldr r1, =(CR_ALT_VECTORS | CR_V4TLD)
ldr r2, =(CR_MPU | CR_DCACHE | CR_ICACHE | CR_DTCM)
mrc p15, 0, r0, c1, c0, 0
bic r0, r1
orr r0, r2
mcr p15, 0, r0, c1, c0, 0
@ Switch to system mode, disable interrupts, setup application stack
msr cpsr_c, #(SR_SYS_MODE | SR_IRQ | SR_FIQ)
msr cpsr_c, #(SR_SYS_MODE | SR_NOINT)
ldr sp, =__STACK_TOP
@ Check entrypoints
@ -156,9 +152,8 @@ _start:
.Lboot_main:
ldr r3, =main
mov lr, #0
bx r3
ldr pc, =main
__mpu_regions:

View File

@ -64,12 +64,12 @@ BootFirm_stub:
@ CPSR:
@ ARM, Supervisor, IRQ/FIQs disabled
@ Flags are undefined
msr cpsr_c, #(SR_SVC_MODE | SR_IRQ | SR_FIQ)
msr cpsr_c, #(SR_SVC_MODE | SR_NOINT)
@ CP15:
@ MPU and Caches are off
@ TCMs are on (location/configuration is undefined)
@ Alternative exception vectors are enabled (0xFFFF0000)
@ High exception vectors are enabled (0xFFFF0000)
ldr r3, =WBINV_DC
ldr r4, =INV_IC
ldr r5, =INITCP15
@ -79,7 +79,7 @@ BootFirm_stub:
@ Registers:
@ R0 = 0x1 or 0x2
@ R1 = 0x23FFFE10
@ R1 = 0x27FFFE00
@ R2 = 0x0003BEEF
@ R3-R14 are undefined

View File

@ -1,102 +0,0 @@
#pragma once
#include "types.h"
static inline void
cpu_membarrier(void) {
__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 4\n\t"
:: "r"(0) : "memory");
}
static inline void
cpu_invalidate_ic(void) {
__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0\n\t"
:: "r"(0) : "memory");
}
static inline void
cpu_invalidate_ic_range(void *base, u32 len) {
u32 addr = (u32)base & ~0x1F;
len >>= 5;
do {
__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 1\n\t"
:: "r"(addr) : "memory");
addr += 0x20;
} while(len--);
}
static inline void
cpu_invalidate_dc(void) {
__asm__ __volatile__("mcr p15, 0, %0, c7, c6, 0\n\t"
:: "r"(0) : "memory");
}
static inline void
cpu_invalidate_dc_range(void *base, u32 len) {
u32 addr = (u32)base & ~0x1F;
len >>= 5;
do {
__asm__ __volatile__("mcr p15, 0, %0, c7, c6, 1"
:: "r"(addr) : "memory");
addr += 0x20;
} while(len--);
}
static inline void
cpu_writeback_dc(void) {
u32 seg = 0, ind;
do {
ind = 0;
do {
__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 2\n\t"
:: "r"(seg | ind) : "memory");
ind += 0x20;
} while(ind < 0x400);
seg += 0x40000000;
} while(seg != 0);
}
static inline
void cpu_writeback_dc_range(void *base, u32 len) {
u32 addr = (u32)base & ~0x1F;
len >>= 5;
do {
__asm__ __volatile__("mcr p15, 0, %0, c7, c10, 1"
:: "r"(addr) : "memory");
addr += 0x20;
} while(len--);
}
static inline
void cpu_writeback_invalidate_dc(void) {
u32 seg = 0, ind;
do {
ind = 0;
do {
__asm__ __volatile__("mcr p15, 0, %0, c7, c14, 2\n\t"
:: "r"(seg | ind) : "memory");
ind += 0x20;
} while(ind < 0x400);
seg += 0x40000000;
} while(seg != 0);
}
static inline
void cpu_writeback_invalidate_dc_range(void *base, u32 len) {
u32 addr = (u32)base & ~0x1F;
len >>= 5;
do {
__asm__ __volatile__("mcr p15, 0, %0, c7, c14, 1"
:: "r"(addr) : "memory");
addr += 0x20;
} while(len--);
}

View File

@ -1,6 +1,6 @@
#include "common.h"
#include "arm.h"
#include "cache.h"
#include "i2c.h"
#include "pxi.h"
@ -24,14 +24,13 @@ bool I2C_readRegBuf(I2cDevice devId, u8 regAddr, u8 *out, u32 size)
int ret;
u32 args[] = {devId, regAddr, (u32)i2c_fcram_buf, size};
cpu_writeback_dc_range(i2c_fcram_buf, size);
cpu_membarrier();
arm_wb_dc_range(i2c_fcram_buf, size);
arm_dsb();
ret = PXI_DoCMD(PXI_I2C_READ, args, 4);
cpu_invalidate_dc_range(i2c_fcram_buf, size);
arm_inv_dc_range(i2c_fcram_buf, size);
memcpy(out, i2c_fcram_buf, size);
return ret;
}
@ -44,8 +43,8 @@ bool I2C_writeRegBuf(I2cDevice devId, u8 regAddr, const u8 *in, u32 size)
u32 args[] = {devId, regAddr, (u32)i2c_fcram_buf, size};
memcpy(i2c_fcram_buf, in, size);
cpu_writeback_dc_range(i2c_fcram_buf, size);
cpu_membarrier();
arm_wb_dc_range(i2c_fcram_buf, size);
arm_dsb();
ret = PXI_DoCMD(PXI_I2C_WRITE, args, 4);
return ret;

View File

@ -31,7 +31,7 @@ XRQ_Vectors:
b . @ FIQs are unused (except for debug?)
XRQ_Reset:
msr cpsr_c, #(SR_ABT_MODE | SR_IRQ | SR_FIQ)
msr cpsr_c, #(SR_ABT_MODE | SR_NOINT)
XRQ_FATAL 0
XRQ_Undefined:
@ -63,7 +63,7 @@ XRQ_MainHandler:
@ Retrieve banked registers
ands r0, r9, #(SR_PMODE_MASK & (0x0F))
orreq r0, #(SR_SYS_MODE)
orr r0, #(0x10 | SR_IRQ | SR_FIQ)
orr r0, #(0x10 | SR_NOINT)
msr cpsr_c, r0 @ Switch to previous mode
mov r0, sp
@ -71,7 +71,7 @@ XRQ_MainHandler:
msr cpsr_c, r10 @ Return to abort
add r2, sp, #(13*4)
stmia r2, {r0,r1,r8,r9}
stmia r2, {r0, r1, r8, r9}
@ Give read/write access to all the memory regions
ldr r0, =0x33333333
@ -95,7 +95,7 @@ XRQ_MainHandler:
mcr p15, 0, r0, c2, c0, 1 @ Inst cacheable 0, 2, 5
@ Enable mpu/caches
ldr r1, =(CR_ENABLE_MPU | CR_ENABLE_DCACHE | CR_ENABLE_ICACHE | CR_ENABLE_DTCM)
ldr r1, =(CR_MPU | CR_DCACHE | CR_ICACHE | CR_DTCM)
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, r1
mcr p15, 0, r0, c1, c0, 0
@ -105,11 +105,11 @@ XRQ_MainHandler:
mov r0, r11
blx r2
msr cpsr, #(SR_SVC_MODE | SR_IRQ | SR_FIQ)
msr cpsr, #(SR_SVC_MODE | SR_NOINT)
mov r0, #0
.LXRQ_WFI:
1:
mcr p15, 0, r0, c7, c0, 4
b .LXRQ_WFI
b 1b
.pool

View File

@ -1,5 +1,7 @@
#pragma once
#include "types.h"
/* Status Register flags */
#define SR_USR_MODE (0x10)
#define SR_FIQ_MODE (0x11)
@ -10,21 +12,291 @@
#define SR_SYS_MODE (0x1F)
#define SR_PMODE_MASK (0x1F)
#define SR_THUMB (1<<5)
#define SR_FIQ (1<<6)
#define SR_IRQ (1<<7)
#define SR_NOINT (SR_FIQ | SR_IRQ)
#define SR_THUMB BIT(5)
#define SR_NOFIQ BIT(6)
#define SR_NOIRQ BIT(7)
#define SR_NOINT (SR_NOFIQ | SR_NOIRQ)
#ifdef ARM9
#define CR_ENABLE_MPU (1<<0)
#define CR_ENABLE_BIGEND (1<<7)
#define CR_ENABLE_DCACHE (1<<2)
#define CR_ENABLE_ICACHE (1<<12)
#define CR_ENABLE_DTCM (1<<16)
#define CR_ENABLE_ITCM (1<<18)
#define CR_ALT_VECTORS (1<<13)
#define CR_CACHE_RROBIN (1<<14)
#define CR_DISABLE_TBIT (1<<15)
#define CR_DTCM_LMODE (1<<17)
#define CR_ITCM_LMODE (1<<19)
#define CR_MPU BIT(0)
#define CR_DCACHE BIT(2)
#define CR_ICACHE BIT(12)
#define CR_DTCM BIT(16)
#define CR_ITCM BIT(18)
#define CR_V4TLD BIT(15)
#define CR_ALT_VECTORS BIT(13)
#define CR_CACHE_RROBIN BIT(14)
#define CR_DTCM_LOAD BIT(17)
#define CR_ITCM_LOAD BIT(19)
#define CR_TCM_LOAD (CR_DTCM_LOAD | CR_ITCM_LOAD)
#define ICACHE_SZ (4096)
#define DCACHE_SZ (4096)
#else // ARM11
#define CR_MMU BIT(0)
#define CR_ALIGN BIT(1)
#define CR_DCACHE BIT(2)
#define CR_ICACHE BIT(12)
#define CR_FLOWPRED BIT(11)
#define CR_HIGHVEC BIT(13)
#define CR_V4TLD BIT(15)
#define CR_UNALIGN BIT(22)
#define CR_DSUBPAGE BIT(23)
#define ACR_RETSTK BIT(0)
#define ACR_DBPRED BIT(1)
#define ACR_SBPRED BIT(2)
#define ACR_FOLDING BIT(3)
#define ACR_EXCL BIT(4)
#define ACR_SMP BIT(5)
#define ICACHE_SZ (16384)
#define DCACHE_SZ (16384)
#endif
#ifndef __ASSEMBLER__
/* ARM Private Memory Region */
#ifdef ARM11
#define REG_ARM_PMR(off, type) ((volatile type*)(0x17E00000 + (off)))
#endif
#define ARM_MCR(cp, op1, reg, crn, crm, op2) asm_v( \
"MCR " #cp ", " #op1 ", %[R], " #crn ", " #crm ", " #op2 "\n\t" \
:: [R] "r"(reg))
#define ARM_MRC(cp, op1, reg, crn, crm, op2) asm_v( \
"MRC " #cp ", " #op1 ", %[R], " #crn ", " #crm ", " #op2 "\n\t" \
: [R] "=r"(reg))
#define ARM_MSR(cp, reg) asm_v( \
"MSR " #cp ", %[R]\n\t" \
:: [R] "r"(reg))
#define ARM_MRS(reg, cp) asm_v( \
"MRS %[R], " #cp "\n\t" \
: [R] "=r"(reg))
#ifdef ARM11
#define ARM_CPS(m) asm_v("CPS " #m)
#define ARM_CPSID(m) asm_v("CPSID " #m)
#define ARM_CPSIE(m) asm_v("CPSIE " #m)
/*
* An Instruction Synchronization Barrier (ISB) flushes the pipeline in the processor
* so that all instructions following the ISB are fetched from cache or memory
* after the ISB has been completed.
*/
static inline void arm_isb(void) {
ARM_MCR(p15, 0, 0, c7, c5, 4);
}
/*
* A Data Memory Barrier (DMB) ensures that all explicit memory accesses before
* the DMB instruction complete before any explicit memory accesses after the DMB instruction start.
*/
static inline void arm_dmb(void) {
ARM_MCR(p15, 0, 0, c7, c10, 5);
}
/* Wait For Interrupt */
static inline void arm_wfi(void) {
asm_v("wfi\n\t");
}
/* Wait For Event */
static inline void arm_wfe(void) {
asm_v("wfe\n\t");
}
/* Send Event */
static inline void arm_sev(void) {
asm_v("sev\n\t");
}
/* Auxiliary Control Registers */
static inline u32 arm_acr_get(void) {
u32 acr;
ARM_MRC(p15, 0, acr, c1, c0, 1);
return acr;
}
static inline void arm_acr_set(u32 acr) {
ARM_MCR(p15, 0, acr, c1, c0, 1);
}
#endif
/*
* A Data Synchronization Barrier (DSB) completes when all
* instructions before this instruction complete.
*/
static inline void arm_dsb(void) {
ARM_MCR(p15, 0, 0, c7, c10, 4);
}
/* Control Registers */
static inline u32 arm_cr_get(void) {
u32 cr;
ARM_MRC(p15, 0, cr, c1, c0, 0);
return cr;
}
static inline void arm_cr_set(u32 cr) {
ARM_MCR(p15, 0, cr, c1, c0, 0);
}
/* Thread ID Registers */
static inline u32 arm_tid_get(void) {
u32 pid;
#ifdef ARM9
ARM_MRC(p15, 0, pid, c13, c0, 1);
#else
ARM_MRC(p15, 0, pid, c13, c0, 4);
#endif
return pid;
}
static inline void arm_tid_set(u32 pid) {
#ifdef ARM9
ARM_MCR(p15, 0, pid, c13, c0, 1);
#else
ARM_MCR(p15, 0, pid, c13, c0, 4);
#endif
}
/* CPU ID */
static inline u32 arm_cpuid(void) {
u32 id;
#ifdef ARM9
id = 0;
#else
ARM_MRC(p15, 0, id, c0, c0, 5);
#endif
return id & 3;
}
/* Status Register */
static inline u32 arm_cpsr_get(void) {
u32 cpsr;
ARM_MRS(cpsr, "cpsr");
return cpsr;
}
static inline void arm_cpsr_c_set(u32 cpsr) {
ARM_MSR("cpsr_c", cpsr);
}
static inline void arm_disable_ints(void) {
#ifdef ARM9
arm_cpsr_c_set(arm_cpsr_get() | SR_NOINT);
#else
ARM_CPSID(if);
#endif
}
static inline void arm_enable_ints(void) {
#ifdef ARM9
arm_cpsr_c_set(arm_cpsr_get() & ~SR_NOINT);
#else
ARM_CPSIE(if);
#endif
}
static inline u32 arm_enter_critical(void) {
u32 stat = arm_cpsr_get();
arm_disable_ints();
return stat & SR_NOINT;
}
static inline void arm_leave_critical(u32 stat) {
arm_cpsr_c_set((arm_cpsr_get() & ~SR_NOINT) | stat);
}
/* Cache functions */
static inline void arm_inv_ic(void) {
ARM_MCR(p15, 0, 0, c7, c5, 0);
}
static inline void arm_inv_ic_range(void *base, u32 len) {
u32 addr = (u32)base & ~0x1F;
len >>= 5;
do {
ARM_MCR(p15, 0, addr, c7, c5, 1);
addr += 0x20;
} while(len--);
}
static inline void arm_inv_dc(void) {
ARM_MCR(p15, 0, 0, c7, c6, 0);
}
static inline void arm_inv_dc_range(void *base, u32 len) {
u32 addr = (u32)base & ~0x1F;
len >>= 5;
do {
ARM_MCR(p15, 0, addr, c7, c6, 1);
addr += 0x20;
} while(len--);
}
static inline void arm_wb_dc(void) {
#ifdef ARM9
u32 seg = 0, ind;
do {
ind = 0;
do {
ARM_MCR(p15, 0, seg | ind, c7, c10, 2);
ind += 0x20;
} while(ind < 0x400);
seg += 0x40000000;
} while(seg != 0);
#else
ARM_MCR(p15, 0, 0, c7, c10, 0);
#endif
}
static inline void arm_wb_dc_range(void *base, u32 len) {
u32 addr = (u32)base & ~0x1F;
len >>= 5;
do {
ARM_MCR(p15, 0, addr, c7, c10, 1);
addr += 0x20;
} while(len--);
}
static inline void arm_wb_inv_dc(void) {
#ifdef ARM9
u32 seg = 0, ind;
do {
ind = 0;
do {
ARM_MCR(p15, 0, seg | ind, c7, c14, 2);
ind += 0x20;
} while(ind < 0x400);
seg += 0x40000000;
} while(seg != 0);
#else
ARM_MCR(p15, 0, 0, c7, c14, 0);
#endif
}
static inline void arm_wb_inv_dc_range(void *base, u32 len) {
u32 addr = (u32)base & ~0x1F;
len >>= 5;
do {
ARM_MCR(p15, 0, addr, c7, c14, 1);
addr += 0x20;
} while(len--);
}
#endif // __ASSEMBLER__

View File

@ -1,68 +0,0 @@
/*
Written by Wolfvak, specially sublicensed under the GPLv2
Read LICENSE for more details
*/
#pragma once
#include <types.h>
#define asm __asm volatile
static inline u32 CPU_ReadCPSR(void)
{
u32 cpsr;
asm("mrs %0, cpsr\n\t":"=r"(cpsr));
return cpsr;
}
static inline void CPU_WriteCPSR_c(u32 cpsr)
{
asm("msr cpsr_c, %0\n\t"::"r"(cpsr));
return;
}
static inline u32 CPU_ReadCR(void)
{
u32 cr;
asm("mrc p15, 0, %0, c1, c0, 0\n\t":"=r"(cr));
return cr;
}
static inline void CPU_WriteCR(u32 cr)
{
asm("mcr p15, 0, %0, c1, c0, 0\n\t"::"r"(cr));
return;
}
static inline void CPU_DisableIRQ(void)
{
#ifdef ARM9
CPU_WriteCPSR_c(CPU_ReadCPSR() | (SR_IRQ | SR_FIQ));
#else
asm("cpsid if\n\t");
#endif
return;
}
static inline void CPU_EnableIRQ(void)
{
#ifdef ARM9
CPU_WriteCPSR_c(CPU_ReadCPSR() & ~(SR_IRQ | SR_FIQ));
#else
asm("cpsie if\n\t");
#endif
return;
}
static inline void CPU_EnterCritical(u32 *ss)
{
*ss = CPU_ReadCPSR();
CPU_DisableIRQ();
return;
}
static inline void CPU_LeaveCritical(u32 *ss)
{
CPU_WriteCPSR_c(*ss);
return;
}

View File

@ -8,13 +8,10 @@
#ifdef ARM9
#define PXI_BASE (0x10008000)
#define PXI_INIT_SYNC_SET (33)
#define PXI_INIT_SYNC_WAIT (66)
#define IRQ_PXI_RX (14)
#else
#define PXI_BASE (0x10163000)
#define IRQ_PXI_RX (83)
#define PXI_INIT_SYNC_SET (66)
#define PXI_INIT_SYNC_WAIT (33)
#endif
enum {
@ -22,6 +19,7 @@ enum {
PXI_BRIGHTNESS,
PXI_I2C_READ,
PXI_I2C_WRITE,
PXI_LEGACY_BOOT,
};
#define PXI_FIFO_LEN (16)
@ -97,7 +95,7 @@ static void PXI_RecvArray(u32 *w, u32 c)
static u32 PXI_DoCMD(u32 cmd, const u32 *args, u32 argc)
{
PXI_Send(cmd);
PXI_Send((argc << 16) | cmd);
PXI_SendArray(args, argc);
return PXI_Recv();
}

View File

@ -6,10 +6,13 @@
#endif
#endif
#define BIT(x) (1 << (x))
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <stddef.h>
#define BIT(x) (1<<(x))
#define asm_v asm __volatile__
typedef uint8_t u8;
typedef uint16_t u16;
@ -30,3 +33,4 @@ typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
#endif