📄 skyeye_mach_sa.c
字号:
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/select.h>
#include "armdefs.h"
#include "sa1100.h"
#define F_CORE (100 * 1024 * 1024) //core frequence
#define F_RTC 32768 //RTC
#define F_OS 3686400 //OS timer
#define RT_SCALE (F_CORE / F_RTC)
#define OS_SCALE (F_CORE / F_OS / 10)
#define UART3_SCALE 200
typedef struct sa_io_t
{
/*interrupt controller */
u32 icpr;
u32 icip;
u32 icfp;
u32 icmr;
u32 iccr;
u32 iclr;
/*real time clock(RTC) */
u32 rcnr;
u32 rtar;
u32 rtsr;
u32 rttr;
u32 rt_scale; /*core frequence to 32.768K */
u32 rt_count;
/*os timer */
u32 oscr;
u32 osmr0, osmr1, osmr2, osmr3;
u32 ower;
u32 ossr;
u32 oier;
u32 os_scale;
/*uart3 controller */
u32 utcr0;
u32 utcr1;
u32 utcr2;
u32 utcr3;
u32 utdr;
u32 utsr0;
u32 utsr1;
u32 uart3_scale;
} sa_io_t;
static sa_io_t sa_io;
static void refresh_irq (ARMul_State *);
static void
sa_io_reset ()
{
memset (&sa_io, 0, sizeof (sa_io));
sa_io.utsr0 = 1; /*always TFS, no others */
sa_io.utsr1 = 0x4;
/*TNF*/};
void
sa_io_write_byte (ARMul_State * state, ARMword addr, ARMword data)
{
printf ("SKYEYE: sa_io_write_byte error\n");
exit (-1);
}
void
sa_io_write_halfword (ARMul_State * state, ARMword addr, ARMword data)
{
printf ("SKYEYE: sa_io_write_halfword error\n");
exit (-1);
}
static void
sa_io_write_word (ARMul_State * state, ARMword addr, ARMword data)
{
switch (addr)
{
/*RTC*/ case RCNR:
sa_io.rcnr = data;
break;
case RTAR:
sa_io.rtar = data;
break;
case RTSR:
sa_io.rtsr |= (data & 0xc);
sa_io.rtsr &= ~(data & 0x3);
break;
case RTTR:
sa_io.rttr = data & 0x3ffffff;
break;
/*OS timer */
case OSCR:
sa_io.oscr = data;
break;
case OSMR0:
sa_io.osmr0 = data;
break;
case OSMR1:
sa_io.osmr1 = data;
break;
case OSMR2:
sa_io.osmr2 = data;
break;
case OSMR3:
sa_io.osmr3 = data;
break;
case OWER:
sa_io.ower |= data & 0x1;
break;
case OSSR:
sa_io.ossr &= ~(data & 0xf);
break;
case OIER:
sa_io.oier = data & 0xf;
break;
/*interrupt control */
case ICPR:
case ICIP:
case ICFP:
/*read only */
break;
case ICMR:
sa_io.icmr = data;
break;
case ICLR:
sa_io.iclr = data;
break;
/*UART 3 */
case UTCR0:
sa_io.utcr0 = data & 0x7f;
break;
case UTCR1:
sa_io.utcr1 = data & 0xf;
break;
case UTCR2:
sa_io.utcr2 = data & 0xff;
break;
case UTCR3:
sa_io.utcr3 = data & 0x3f;
break;
case UTDR:
{
char c = data;
write (skyeye_config.uart.fd_out, &c, 1);
//log_msg("UTDR write\n");
}
break;
case UTSR0:
sa_io.utsr0 &= ~(data & 0x1b);
break;
default:
//log_msg("addr %x unknow\n", addr);
;
};
};
ARMword
sa_io_read_byte (ARMul_State * state, ARMword addr)
{
printf ("SKYEYE: sa_io_read_byte error\n");
exit (-1);
}
ARMword
sa_io_read_halfword (ARMul_State * state, ARMword addr)
{
printf ("SKYEYE: sa_io_read_halfword error\n");
exit (-1);
}
ARMword
sa_io_read_word (ARMul_State * state, ARMword addr)
{
u32 data;
switch (addr)
{
/*RTC*/ case RCNR:
data = sa_io.rcnr;
break;
case RTAR:
data = sa_io.rtar;
break;
case RTSR:
data = sa_io.rtsr;
break;
case RTTR:
data = sa_io.rttr;
break;
/*OS timer */
case OSCR:
data = sa_io.oscr;
break;
case OSMR0:
data = sa_io.osmr0;
break;
case OSMR1:
data = sa_io.osmr1;
break;
case OSMR2:
data = sa_io.osmr2;
break;
case OSMR3:
data = sa_io.osmr3;
break;
case OWER:
data = sa_io.ower;
break;
case OSSR:
data = sa_io.ossr;
break;
case OIER:
data = sa_io.oier;
break;
/*interrupt controler */
case ICPR:
data = sa_io.icpr;
break;
case ICIP:
data = (sa_io.icmr & sa_io.icpr) & ~sa_io.iclr;
break;
case ICFP:
data = (sa_io.icmr & sa_io.icpr) & sa_io.iclr;
break;
case ICMR:
data = sa_io.icmr;
break;
case ICLR:
data = sa_io.iclr;
break;
/*UART 3 */
case UTCR0:
data = sa_io.utcr0;
break;
case UTCR1:
data = sa_io.utcr1;
break;
case UTCR2:
data = sa_io.utcr2;
break;
case UTCR3:
data = sa_io.utcr3;
break;
case UTDR:
{
char c;
read (skyeye_config.uart.fd_in, &c, 1);
data = c;
}
sa_io.utsr0 = 1; /*always TFS, no others */
sa_io.utsr1 = 0x4;
/*TNF*/ break;
case UTSR0:
data = sa_io.utsr0;
break;
case UTSR1:
data = sa_io.utsr1;
break;
default:
//log_msg("addr %x unknow\n", addr);
data = 0;
};
return data;
};
static void
sa_io_do_cycle (ARMul_State * state)
{
/*RTC*/ if (++sa_io.rt_scale >= RT_SCALE)
{
sa_io.rt_scale = 0;
if (sa_io.rt_count++ == (sa_io.rttr & 0xffff))
{
sa_io.rt_count = 0;
if (sa_io.rcnr++ == sa_io.rtar)
{
if (sa_io.rtsr & 0x4)
{
sa_io.rtsr |= 0x1;
};
}
if (sa_io.rtsr & 0x8)
{
sa_io.rtsr |= 0x2;
}
}
};
/*OS timer */
if (++sa_io.os_scale >= OS_SCALE)
{
u32 mask = 0;
u32 count;
sa_io.os_scale = 0;
count = sa_io.oscr++;
if (count == sa_io.osmr0)
mask = 1;
if (count == sa_io.osmr1)
mask |= 0x2;
if (count == sa_io.osmr2)
mask |= 0x4;
if (count == sa_io.osmr3)
{
mask |= 0x8;
if (sa_io.ower & 1)
state->NresetSig = LOW;
}
sa_io.ossr |= mask;
}
/*UART 3 */
if (++sa_io.uart3_scale > UART3_SCALE)
{
fd_set rset;
struct timeval tv;
sa_io.utsr0 |= 1; /*always TFS, no others */
sa_io.utsr1 |= 0x4;
/*TNF*/ sa_io.uart3_scale = 0;
FD_ZERO (&rset);
FD_SET (skyeye_config.uart.fd_in, &rset);
tv.tv_sec = 0;
tv.tv_usec = 0;
if (select (skyeye_config.uart.fd_in + 1, &rset, NULL, NULL, &tv) == 1)
{
sa_io.utsr1 |= 0x2; //RNE
sa_io.utsr0 |= 0x4; //RID
}
}
/*reset interrupt pin status */
refresh_irq (state);
};
static void
refresh_irq (ARMul_State * state)
{
u32 irq = 0;
u32 mask;
/*RTC*/ if ((sa_io.rtsr & 0x1) && (sa_io.rtsr & 0x4))
irq |= RTC_ALARM_IRQ;
if ((sa_io.rtsr & 0x2) && (sa_io.rtsr & 0x8))
irq |= RTC_HZ_IRQ;
/*OS time */
mask = sa_io.oier & sa_io.ossr;
irq |= (mask << OS_IRQ_SHF);
/*UART3 */
if ((sa_io.utcr3 & 0x8) && (sa_io.utsr0 & 0x6))
irq |= UART3_IRQ;
if (sa_io.utsr0 & 0x38)
irq |= UART3_IRQ;
if ((sa_io.utcr3 & 0x10) && (sa_io.utsr0 & 0x1))
irq |= UART3_IRQ;
sa_io.icpr = irq;
sa_io.icip = (sa_io.icmr & sa_io.icpr) & ~sa_io.iclr;
sa_io.icfp = (sa_io.icmr & sa_io.icpr) & sa_io.iclr;
state->NirqSig = sa_io.icip ? LOW : HIGH;
state->NfiqSig = sa_io.icfp ? LOW : HIGH;
}
void
sa1100_mach_init (ARMul_State * state, machine_config_t * mc)
{
//chy 2003-08-19, setprocessor
ARMul_SelectProcessor (state, ARM_v4_Prop);
//chy 2004-05-09, set lateabtSig
state->lateabtSig = LOW;
state->Reg[1] = 109; /*adsbitsy machine id. */
sa_io_reset ();
mc->mach_io_do_cycle = sa_io_do_cycle;
mc->mach_io_reset = sa_io_reset;
mc->mach_io_read_byte = sa_io_read_byte;
mc->mach_io_write_byte = sa_io_write_byte;
mc->mach_io_read_halfword = sa_io_read_halfword;
mc->mach_io_write_halfword = sa_io_write_halfword;
mc->mach_io_read_word = sa_io_read_word;
mc->mach_io_write_word = sa_io_write_word;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -