📄 skyeye_mach_s3c44b0.c
字号:
/*
skyeye_mach_s3c44b0.c - define machine s3c44b0 for skyeye
Copyright (C) 2003 Skyeye Develop Group
for help please send mail to <skyeye-developer@lists.gro.clinux.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* 7/19/2003 init this file.
* should be completed. who can do it?
* walimis <wlm@student.dlut.edu.cn>
*
* */
#include "armdefs.h"
#include "s3c44b0.h"
//zzc:2005-1-1
#ifdef __CYGWIN__
//chy 2005-07-28
#include <time.h>
struct timeval
{
long tv_sec;
long tv_usec;
};
#endif
void s3c44b0_io_write_word (ARMul_State * state, ARMword addr, ARMword data);
ARMword s3c44b0_io_read_word (ARMul_State * state, ARMword addr);
/* s3c44b0 Internal IO Registers
* */
typedef struct s3c44b0_io
{
/*System Manager control */
ARMword syscfg;
/*Interrupt Controller Registers */
ARMword intcon;
ARMword intpnd;
ARMword intmod;
ARMword intmsk;
ARMword i_pslv;
ARMword i_pmst;
ARMword i_cslv;
ARMword i_cmst;
ARMword i_ispr;
ARMword i_ispc;
ARMword f_ispr;
ARMword f_ispc;
/*UART Registers */
ARMword ulcon0;
ARMword ulcon1;
ARMword ucon0;
ARMword ucon1;
ARMword ufcon0;
ARMword ufcon1;
ARMword umcon0;
ARMword umcon1;
ARMword utrstat0;
ARMword utrstat1;
ARMword uerstat0;
ARMword uerstat1;
ARMword ufstat0;
ARMword ufstat1;
ARMword umstat0;
ARMword umstat1;
ARMword utxh0;
ARMword utxh1;
ARMword urxh0;
ARMword urxh1;
ARMword ubrdiv0;
ARMword ubrdiv1;
/*Timers Registers */
ARMword tcfg0;
ARMword tcfg1;
ARMword tcon;
int tcntb[TIMER_NUM];
int tcnt[TIMER_NUM];
int tcmpb[TIMER_NUM]; /*timer5 has no tcmpb register. */
int tcmp[TIMER_NUM]; /*timer5 has no tcmpb register. */
int tcnto[TIMER_NUM];
} s3c44b0_io_t;
static s3c44b0_io_t s3c44b0_io;
#define io s3c44b0_io
/*some defines*/
#define ENABLE_IRQ ~io.intcon & 0x2
#define ENABLE_FIQ ~io.intcon & 0x1
static void
s3c44b0_update_int (ARMul_State * state)
{
ARMword requests = io.intpnd & (~io.intmsk & INT_MASK_INIT);
state->NfiqSig = (requests & io.intmod) ? LOW : HIGH;
state->NirqSig = (requests & ~io.intmod) ? LOW : HIGH;
}
static void
s3c44b0_set_interrupt (unsigned int irq)
{
/*if (ENABLE_IRQ){
io.i_ispr = (1 << interrupt);
} */
if (ENABLE_IRQ | ENABLE_FIQ)
{
io.intpnd |= (1 << irq);
}
}
static void
s3c44b0_io_reset (ARMul_State * state)
{
memset (&s3c44b0_io, 0, sizeof (s3c44b0_io));
io.syscfg = 0x01;
/*Interrupt register reset */
io.intcon = 0x7;
io.intmsk = INT_MASK_INIT;
io.i_pslv = 0x1b1b1b1b;
io.i_pmst = 0x00001f1b;
io.i_cslv = 0x1b1b1b1b;
io.i_cmst = 0x0000001b;
io.i_ispr = 0x0;
io.i_ispc = 0x0;
/*UART*/ io.utrstat0 = io.utrstat1 = 0x6;
}
/* test timer register tcon's bit.
* */
static int
timer_op (int n, int op)
{
if (n == 0)
return TIMER_OP (io.tcon, n, op);
else
{
if (n == 5 && op == TIMER_OP_RELOAD)
return TIMER_OP (io.tcon, n + 1, op - 1);
else
return TIMER_OP (io.tcon, n + 1, op);
}
}
/* get timer interrupt num.
* */
static
get_timer_int (int i)
{
switch (i)
{
case 0:
return TIMER_INT (0);
break;
case 1:
return TIMER_INT (1);
break;
case 2:
return TIMER_INT (2);
break;
case 3:
return TIMER_INT (3);
break;
case 4:
return TIMER_INT (4);
break;
case 5:
return TIMER_INT (5);
break;
}
}
/*s3c44b0 io_do_cycle*/
void
s3c44b0_io_do_cycle (ARMul_State * state)
{
int i;
/*Timer */
for (i = 0; i < TIMER_NUM; i++)
{
if (timer_op (i, TIMER_OP_START))
{
if (io.tcnt[i] > 0)
{
io.tcnt[i]--;
io.tcmp[i]--;
}
if (io.tcnt[i] == 0)
{
if (timer_op (i, TIMER_OP_RELOAD))
{
io.tcnt[i] = io.tcntb[i];
io.tcmp[i] = io.tcmpb[i];
io.tcnto[i] = io.tcntb[i];
s3c44b0_set_interrupt (get_timer_int (i));
s3c44b0_update_int (state);
}
//s3c44b0_set_interrupt(get_timer_int(i));
//s3c44b0_update_int(state);
}
}
}
/*UART*/ if (!(io.intpnd & INT_URXD0) || !(io.intpnd & INT_URXD1))
{
fd_set rfds;
struct timeval tv;
FD_ZERO (&rfds);
FD_SET (skyeye_config.uart.fd_in, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
if (select (skyeye_config.uart.fd_in + 1, &rfds, NULL, NULL, &tv) == 1)
{
unsigned char buf;
int n;
n = read (skyeye_config.uart.fd_in, &buf, 1);
if (n)
{
io.urxh0 = io.urxh1 = (int) buf;
io.utrstat0 |= UART_LSR_DR;
io.utrstat1 |= UART_LSR_DR;
if ((io.ucon0 & 0x3) == 0x1)
{
s3c44b0_set_interrupt (INT_URXD0);
s3c44b0_update_int (state);
return;
}
if ((io.ucon1 & 0x3) == 0x1)
{
s3c44b0_set_interrupt (INT_URXD1);
s3c44b0_update_int (state);
return;
}
}
}
}
// s3c44b0_update_int(state);
}
/* IO Read Routine
* */
ARMword
s3c44b0_io_read_byte (ARMul_State * state, ARMword addr)
{
s3c44b0_io_read_word (state, addr);
/*printf("SKYEYE: s3c44b0_io_read_byte error\n");
exit(-1); */
}
ARMword
s3c44b0_io_read_halfword (ARMul_State * state, ARMword addr)
{
s3c44b0_io_read_word (state, addr);
/*printf("SKYEYE: s3c44b0_io_read_halfword error\n");
exit(-1); */
}
ARMword
s3c44b0_io_read_word (ARMul_State * state, ARMword addr)
{
ARMword data = -1;
switch (addr)
{
case SYSCFG:
data = io.syscfg;
printf ("%s (addr = 0x%08x), pc:%x, NumInstrs:%x\n", __FUNCTION__, addr,
state->pc, state->NumInstrs);
//printf("instr:%x\n",state->loaded);
break;
/*Interrupt */
case INTCON:
data = io.intcon;
break;
case INTMOD:
data = io.intmod;
break;
case INTPND:
data = io.intpnd;
break;
case INTMSK:
data = io.intmsk;
break;
case I_PSLV:
data = io.i_pslv;
break;
case I_PMST:
data = io.i_pmst;
break;
case I_CSLV:
data = io.i_cslv;
break;
case I_CMST:
data = io.i_cmst;
break;
case I_ISPR:
{
/*find which interrupt is pending */
int i;
for (i = 0; i < 26; i++)
{
if (io.intpnd & (1 << i))
break;
}
if (i < 26)
{
data = (1 << i);
}
else
data = 0;
}
//data = io.i_ispr;
break;
case I_ISPC:
data = io.i_ispc;
break;
case F_ISPR:
data = io.f_ispr;
break;
case F_ISPC:
data = io.f_ispc;
break;
/*UART*/ case ULCON0:
data = io.ulcon0;
break;
case ULCON1:
data = io.ulcon1;
break;
case UCON0:
data = io.ucon0;
break;
case UCON1:
data = io.ucon1;
break;
case UFCON0:
data = io.ufcon0;
break;
case UFCON1:
data = io.ufcon1;
break;
case UMCON0:
data = io.umcon0;
break;
case UMCON1:
data = io.umcon1;
break;
case UTRSTAT0:
data = io.utrstat0;
break;
case UTRSTAT1:
data = io.utrstat1;
break;
case UERSTAT0:
data = io.uerstat0;
break;
case UERSTAT1:
data = io.uerstat1;
break;
case UFSTAT0:
data = io.ufstat0;
break;
case UFSTAT1:
data = io.ufstat1;
break;
case UMSTAT0:
data = io.umstat0;
break;
case UMSTAT1:
data = io.umstat1;
break;
case URXH0:
data = io.urxh0;
io.utrstat0 &= ~UART_LSR_DR;
break;
case URXH1:
data = io.urxh1;
io.utrstat1 &= ~UART_LSR_DR;
break;
case UBRDIV0:
data = io.ubrdiv0;
break;
case UBRDIV1:
data = io.ubrdiv1;
break;
/*Timer */
case TCFG0:
data = io.tcfg0;
break;
case TCFG1:
data = io.tcfg1;
break;
case TCON:
data = io.tcon;
break;
case TCNTB0:
case TCMPB0:
case TCNTO0:
case TCNTB1:
case TCMPB1:
case TCNTO1:
case TCNTB2:
case TCMPB2:
case TCNTO2:
case TCNTB3:
case TCMPB3:
case TCNTO3:
case TCNTB4:
case TCMPB4:
case TCNTO4:
case TCNTB5:
case TCNTO5:
break;
default:
SKYEYE_DBG ("%s (addr = 0x%08x)\n", __FUNCTION__, addr);
break;
}
return data;
}
/* IO Write Routine
* */
void
s3c44b0_io_write_byte (ARMul_State * state, ARMword addr, ARMword data)
{
s3c44b0_io_write_word (state, addr, data);
/*printf("SKYEYE: s3c44b0_io_write_byte error\n");
exit(-1); */
}
void
s3c44b0_io_write_halfword (ARMul_State * state, ARMword addr, ARMword data)
{
s3c44b0_io_write_word (state, addr, data);
printf ("SKYEYE: s3c44b0_io_write_halfword error\n");
exit (-1);
}
void
s3c44b0_io_write_word (ARMul_State * state, ARMword addr, ARMword data)
{
switch (addr)
{
case SYSCFG:
io.syscfg = data;
break;
/*Interrupt */
case INTCON:
io.intcon = data;
break;
/*case INTPND:
break; */
case INTMOD:
io.intmod = data;
break;
case INTMSK:
io.intmsk = data;
break;
case I_PSLV:
io.i_pslv = data;
break;
case I_PMST:
io.i_pmst = data;
break;
case I_CSLV:
io.i_cslv = data;
break;
case I_CMST:
io.i_cmst = data;
break;
/*case I_ISPR:
io.i_ispr = data;
break; */
case I_ISPC:
io.intpnd &= (~data & INT_MASK_INIT);
//io.i_ispr = 0;
//s3c44b0_update_int(state);
break;
/*case F_ISPR:
io.f_ispr = data;
break; */
case F_ISPC:
io.intpnd &= (~data & INT_MASK_INIT);
//s3c44b0_update_int(state);
break;
/*UART*/ case ULCON0:
io.ulcon0 = data;
break;
case ULCON1:
io.ulcon1 = data;
break;
case UCON0:
io.ucon0 = data;
break;
case UCON1:
io.ucon1 = data;
break;
case UFCON0:
io.ufcon0 = data;
break;
case UFCON1:
io.ufcon1 = data;
break;
case UMCON0:
io.umcon0 = data;
break;
case UMCON1:
io.umcon1 = data;
break;
/*read only */
/*case UTRSTAT0:
io.utrstat0 = data;
break;
case UTRSTAT1:
io.utrstat1 = data;
break;
case UERSTAT0:
io.uerstat0 = data;
break;
case UERSTAT1:
io.uerstat1 = data;
break;
case UFSTAT0:
io.ufstat0 = data;
break;
case UFSTAT1:
io.ufstat1 = data;
break;
case UMSTAT0:
io.umstat0 = data;
break;
case UMSTAT1:
io.umstat1 = data;
break; */
case UTXH0:
{
char c = data;
write (skyeye_config.uart.fd_out, &c, 1);
io.utrstat0 |= UART_LSR_THRE | UART_LSR_TEMT;
if ((io.ucon0 & 0xc) == 0x04)
{
s3c44b0_set_interrupt (INT_UTXD0);
s3c44b0_update_int (state);
}
}
break;
case UTXH1:
io.utxh1 = data;
break;
case URXH0:
io.urxh0 = data;
break;
case URXH1:
io.urxh1 = data;
break;
case UBRDIV0:
io.ubrdiv0 = data;
break;
case UBRDIV1:
io.ubrdiv1 = data;
break;
/*Timer */
case TCFG0:
io.tcfg0 = data;
break;
case TCFG1:
io.tcfg1 = data;
break;
case TCON:
io.tcon = data;
{
int i;
int rel;
for (i = 0; i < TIMER_NUM; i++)
{
rel = timer_op (i, TIMER_OP_MANUAL);
//if(timer_op(i, TIMER_OP_MANUAL)){
if (rel)
{
io.tcnt[i] = io.tcntb[i];
io.tcmp[i] = io.tcmpb[i];
io.tcnto[i] = io.tcntb[i];
}
}
}
break;
case TCNTB0:
case TCNTB1:
case TCNTB2:
case TCNTB3:
case TCNTB4:
{
int n = (addr - TCNTB0) / 12;
io.tcntb[n] = data * 480;
}
case TCMPB0:
case TCMPB1:
case TCMPB2:
case TCMPB3:
case TCMPB4:
{
int n = (addr - TCNTB0) / 12;
io.tcmpb[n] = data;
}
break;
case TCNTB5:
io.tcntb[5] = data; //* 480;
break;
default:
SKYEYE_DBG ("%s(0x%08x) = 0x%08x\n", __FUNCTION__, addr, data);
break;
}
}
void
s3c44b0_mach_init (ARMul_State * state, machine_config_t * this_mach)
{
ARMul_SelectProcessor (state, ARM_v4_Prop);
state->lateabtSig = HIGH;
state->Reg[1] = 178;
this_mach->mach_io_do_cycle = s3c44b0_io_do_cycle;
this_mach->mach_io_reset = s3c44b0_io_reset;
this_mach->mach_io_read_word = s3c44b0_io_read_word;
this_mach->mach_io_read_halfword = s3c44b0_io_read_halfword;
this_mach->mach_io_read_byte = s3c44b0_io_read_byte;
this_mach->mach_io_write_word = s3c44b0_io_write_word;
this_mach->mach_io_write_halfword = s3c44b0_io_write_halfword;
this_mach->mach_io_write_byte = s3c44b0_io_write_byte;
this_mach->mach_update_int = s3c44b0_update_int;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -