kolibrios-fun/contrib/other/uarm/pxa255_IC.c

105 lines
2.0 KiB
C
Raw Normal View History

#include "pxa255_IC.h"
#include "mem.h"
static void pxa255icPrvHandleChanges(Pxa255ic* ic){
Boolean nowIrq, nowFiq;
UInt32 unmasked = ic->ICPR & ic->ICMR;
nowFiq = (unmasked & ic->ICLR) != 0;
nowIrq = (unmasked & ~ic->ICLR) != 0;
if(nowFiq != ic->wasFiq) cpuIrq(ic->cpu, true, nowFiq);
if(nowIrq != ic->wasIrq) cpuIrq(ic->cpu, false, nowIrq);
ic->wasFiq = nowFiq;
ic->wasIrq = nowIrq;
}
static Boolean pxa255icPrvMemAccessF(void* userData, UInt32 pa, UInt8 size, Boolean write, void* buf){
Pxa255ic* ic = userData;
UInt32 val = 0;
if(size != 4) {
err_str(__FILE__ ": Unexpected ");
// err_str(write ? "write" : "read");
// err_str(" of ");
// err_dec(size);
// err_str(" bytes to 0x");
// err_hex(pa);
// err_str("\r\n");
return true; //we do not support non-word accesses
}
pa = (pa - PXA255_IC_BASE) >> 2;
if(write){
if(pa == 1) ic->ICMR = *(UInt32*)buf;
else if(pa == 2) ic->ICLR = *(UInt32*)buf;
else if(pa == 5) ic->ICCR = *(UInt32*)buf;
else return true;
pxa255icPrvHandleChanges(ic);
}
else{
switch(pa){
case 0:
val = ic->ICPR & ic->ICMR & ~ic->ICLR;
break;
case 1:
val = ic->ICMR;
break;
case 2:
val = ic->ICLR;
break;
case 3:
val = ic->ICPR & ic->ICMR & ic->ICLR;
break;
case 4:
val = ic->ICPR;
break;
case 5:
val = ic->ICCR;
break;
}
*(UInt32*)buf = val;
}
return true;
}
Boolean pxa255icInit(Pxa255ic* ic, ArmCpu* cpu, ArmMem* physMem){
__mem_zero(ic, sizeof(Pxa255ic));
ic->cpu = cpu;
return memRegionAdd(physMem, PXA255_IC_BASE, PXA255_IC_SIZE, pxa255icPrvMemAccessF, ic);
}
void pxa255icInt(Pxa255ic* ic, UInt8 intNum, Boolean raise){ //interrupt caused by emulated hardware
UInt32 old_, new_;
old_ = new_ = ic->ICPR;
if(raise) new_ |= (1UL << intNum);
else new_ &=~ (1UL << intNum);
if(new_ != old_){
ic->ICPR = new_;
pxa255icPrvHandleChanges(ic);
}
}