⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skyeye_mach_s3c44b0.c

📁 嵌入式的开发的一个开源仿真程序源码,其是开源的,很不错的奉献给大家
💻 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 + -