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

📄 skyeye_mach_at91rm92.c

📁 这是Skyeye 0.9 版本的源代码
💻 C
字号:
/*
	skyeye_mach_at91rm92.c - define machine AT91RM9200 for skyeye
	Copyright (C) 2004 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 
 
*/
/*
 * 10/31/2004 	complete UART, Timer, Interrupt, now it can boot ARMLinux successfully.
 *		walimis <wlm@student.dlut.edu.cn> 
 * 5/23/2004 	init this file.
 *		walimis <wlm@student.dlut.edu.cn> 
 *		
 * */
#include "armdefs.h"
#include "at91rm92.h"
//zzc:2005-1-1
#ifdef __CYGWIN__
//chy 2005-07-28
#include <time.h>

struct timeval
{
  long tv_sec;
  long tv_usec;
};
#endif


typedef struct at91rm92_io
{
  u32 ivr;			/*AIC Interrupt Vector Register */
  u32 fvr;			/*AIC FIQ Vector Register */
  u32 isr;			/*AIC Interrupt Status Register */
  u32 ipr;			/*AIC Interrupt Pending Register */
  u32 imr;			/*AIC Interrupt Mask Register */
  u32 cisr;
  u32 iecr;
  u32 idcr;
  u32 iccr;
  u32 iscr;
  u32 eoicr;
  u32 spu;

  struct at91rm92_st_io st;	/*system timer */
  struct at91rm92_uart_io uart0;	/*uart0 */

  int tc_prescale;


} at91rm92_io_t;
static at91rm92_io_t at91rm92_io;
#define io at91rm92_io

static void
at91rm92_update_int (ARMul_State * state)
{
  ARMword requests = io.ipr & io.imr;
  state->NfiqSig = (requests & 0x00001) ? LOW : HIGH;
  state->NirqSig = (requests & 0xfffffffe) ? LOW : HIGH;
}

/* new added functions
 * */
static void
at91rm92_set_intr (u32 interrupt)
{
  io.ipr |= (1 << interrupt);
}
static int
at91rm92_pending_intr (u32 interrupt)
{
  return ((io.ipr & (1 << interrupt)));
}

#if 0
static void
at91rm92_update_intr (void *mach)
{
  struct machine_config *mc = (struct machine_config *) mach;
  ARMul_State *state = (ARMul_State *) mc->state;
  ARMword requests = io.ipr & io.imr;
  state->NfiqSig = (requests & 0x00001) ? LOW : HIGH;
  state->NirqSig = (requests & 0x3fffe) ? LOW : HIGH;

}
static int
at91rm92_mem_read_byte (void *mach, u32 addr, u32 * data)
{
  struct machine_config *mc = (struct machine_config *) mach;
  ARMul_State *state = (ARMul_State *) mc->state;
  *data = (u32) mem_read_char (state, addr);
}
static int
at91rm92_mem_write_byte (void *mach, u32 addr, u32 data)
{
  struct machine_config *mc = (struct machine_config *) mach;
  ARMul_State *state = (ARMul_State *) mc->state;
  mem_write_char (state, addr, (char) data);
}
#endif

static void
at91rm92_io_reset (ARMul_State * state)
{

  io.uart0.csr = 0x00000202;
  /* CHRL : 11 8bit
   * */
  io.uart0.mr = 0x000000c0;
  io.uart0.brgr = 0x000000c0;

}

/*at91rm92 io_do_cycle*/
static void
at91rm92_io_do_cycle (ARMul_State * state)
{

  if (io.st.pimr != 0)
    {
      if (io.st.piv_dc == 0)
	{
	  io.st.sr |= AT91RM92_ST_PITS;
	  if (io.st.imr & AT91RM92_ST_PITS)
	    {
	      io.ipr |= AT91RM92_ID_SYS;
	    }
	  io.st.piv_dc = io.st.pimr;
	}
      else
	{
	  io.st.piv_dc--;
	}
    }
  if ((io.uart0.imr & AT91RM92_US_RXRDY))
    {
      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, i;
	  n = read (skyeye_config.uart.fd_in, &buf, 1);
	  if (n)
	    {
	      io.uart0.rhr = (int) buf;
	      /* Receiver Ready
	       * */
	      io.uart0.csr |= AT91RM92_US_RXRDY;
	      /* pending usart0 interrupt
	       * */
	      io.ipr |= AT91RM92_ID_US0;
	    }
	}
    }				/* if (rcr > 0 && ... */
  at91rm92_update_int (state);
}

static void
at91rm92_uart_read (u32 offset, u32 * data)
{
  switch (offset)
    {
    case US_MR:
      *data = io.uart0.mr;
      break;
    case US_IMR:
      *data = io.uart0.imr;
      break;
    case US_CSR:
      *data = io.uart0.csr;
      break;
    case US_RHR:
      /* receive char
       * */
      *data = io.uart0.rhr;
      io.uart0.csr &= (~AT91RM92_US_RXRDY);
      break;
    case US_BRGR:
      *data = io.uart0.brgr;
      break;
    case US_RTOR:
      *data = io.uart0.rtor;
      break;
    case US_TTGR:
      *data = io.uart0.ttgr;
      break;
    case US_FIDI:
      *data = io.uart0.fidi;
      break;
    case US_NER:
      *data = io.uart0.ner;
      break;
    case US_IF:
      *data = io.uart0.us_if;
      break;
    }
  SKYEYE_DBG ("%s(0x%x, 0x%x)\n", __func__, offset, data);
}

static void
at91rm92_uart_write (ARMul_State * state, u32 offset, u32 data)
{

  SKYEYE_DBG ("at91rm92_uart_write(0x%x, 0x%x)\n", offset, data);
  switch (offset)
    {
    case US_CR:
      io.uart0.cr = data;
      break;
    case US_MR:
      io.uart0.mr = data;
      break;
    case US_IER:
      //io.uart0.ier = data;
      io.uart0.imr |= (data & 0x000f3fff);
      if (io.uart0.imr)
	{
	  io.ipr |= AT91RM92_ID_US0;
	  at91rm92_update_int (state);
	}
      break;
    case US_IDR:
      /* disable usart0 corresponding interrupt
       * */
      io.uart0.imr &= (~data) & 0x000f3fff;
      break;
    case US_THR:
      {
	char c = data;
	write (skyeye_config.uart.fd_out, &c, 1);
	io.uart0.csr |= AT91RM92_US_TXRDY;
      }
      //io.uart0.thr = data;
      break;
    case US_BRGR:
      io.uart0.brgr = data;
      break;
    case US_RTOR:
      io.uart0.rtor = data;
      break;
    case US_TTGR:
      io.uart0.ttgr = data;
      break;
    case US_FIDI:
      io.uart0.fidi = data;
      break;
    case US_IF:
      io.uart0.us_if = data;
      break;
    }
  SKYEYE_DBG ("%s(0x%x, 0x%x)\n", __func__, offset, data);
}



static void
at91rm92_st_read (u32 offset, u32 * data)
{
  switch (offset)
    {
    case ST_PIMR:
      *data = io.st.pimr;
      break;
    case ST_WDMR:
      *data = io.st.wdmr;
      break;
    case ST_RTMR:
      *data = io.st.rtmr;
      break;
    case ST_SR:
      *data = io.st.sr;
      /* reinitialize it to zero */
      io.st.sr = 0x0;
      break;
    case ST_IMR:
      *data = io.st.imr;
      break;
    case ST_RTAR:
      *data = io.st.rtar;
      break;
    case ST_CRTR:
      *data = io.st.crtr;
      break;
    }
}
static void
at91rm92_st_write (ARMul_State * state, u32 offset, u32 data)
{
  switch (offset)
    {
    case ST_CR:
      io.st.cr = data;
      io.st.wdv_dc = io.st.wdmr;
      break;
    case ST_PIMR:
      io.st.pimr = data;
      io.st.piv_dc = data;
      break;
    case ST_WDMR:
      io.st.wdmr = data;
      io.st.wdv_dc = data;
      break;
    case ST_RTMR:
      io.st.rtmr = data;
      io.st.rtpres_dc = data;
      break;
    case ST_IER:
      io.st.imr |= (data & 0x0000000f);
      if (io.st.imr)
	{
	  io.ipr |= AT91RM92_ID_SYS;
	  at91rm92_update_int (state);
	}
      break;
    case ST_IDR:
      io.st.imr &= (~data) & 0xf;
      break;
    case ST_RTAR:
      io.st.rtar = data;
      break;
    }
}

static ARMword
at91rm92_io_read_word (ARMul_State * state, ARMword addr)
{

  ARMword data = -1;
  int i;
  /*uart0 */
  if ((addr >= AT91RM92_UART_BASE0) &&
      (addr < (AT91RM92_UART_BASE0 + AT91RM92_UART_SIZE)))
    {
      at91rm92_uart_read ((u32) (addr - AT91RM92_UART_BASE0), (u32 *) & data);
    }
  if ((addr >= AT91RM92_ST_BASE0) &&
      (addr < (AT91RM92_ST_BASE0 + AT91RM92_ST_SIZE)))
    {
      at91rm92_st_read ((u32) (addr - AT91RM92_ST_BASE0), (u32 *) & data);
    }
  switch (addr)
    {
    case AIC_IVR:		/* IVR */
      data = io.ipr;
      SKYEYE_DBG ("IVR irqs=%x ", data);
      for (i = 0; i < 32; i++)
	if (data & (1 << i))
	  break;
      if (i < 32)
	{
	  data = i;
	  io.ipr &= ~(1 << data);
	  at91rm92_update_int (state);
	}
      else
	data = 0;
      io.ivr = data;
      SKYEYE_DBG ("read IVR=%d\n", data);
      break;
    case AIC_ISR:		/* ISR: interrupt status register */
      data = io.ivr;
      break;
    case AIC_IMR:		/* IMR */
      data = io.imr;
      break;
    case AIC_CISR:		/* CISR: Core interrupt status register */
      data = io.cisr;
      data = io.imr;
      SKYEYE_DBG ("read CISR=%x,%x\n", data, io.intsr);
      break;
    default:
      break;
    }
  return data;
}

static ARMword
at91rm92_io_read_byte (ARMul_State * state, ARMword addr)
{
  SKYEYE_DBG ("SKYEYE: at91rm92_io_read_byte error\n");
  at91rm92_io_read_word (state, addr);
}

static ARMword
at91rm92_io_read_halfword (ARMul_State * state, ARMword addr)
{
  SKYEYE_DBG ("SKYEYE: at91rm92_io_read_halfword error\n");
  at91rm92_io_read_word (state, addr);
}

static void
at91rm92_io_write_word (ARMul_State * state, ARMword addr, ARMword data)
{
  if ((addr >= AT91RM92_UART_BASE0) &&
      (addr < AT91RM92_UART_BASE0 + AT91RM92_UART_SIZE))
    {
      at91rm92_uart_write (state, addr - AT91RM92_UART_BASE0, data);
    }
  if ((addr >= AT91RM92_ST_BASE0) &&
      (addr < (AT91RM92_ST_BASE0 + AT91RM92_ST_SIZE)))
    {
      at91rm92_st_write (state, addr - AT91RM92_ST_BASE0, data);
    }
  switch (addr)
    {
    case AIC_IECR:		/* IECR */
      io.iecr = data;
      io.imr |= data;
      break;
    case AIC_IDCR:		/* IDCR */
      io.idcr = data;
      io.imr &= ~data;
      break;
    case AIC_ICCR:		/* CLEAR interrupts */
      io.iccr = data;
      io.ipr &= ~data;
      break;
    case AIC_EOICR:		/* EOI */
      io.eoicr = data;
      io.ipr &= ~data;
      at91rm92_update_int (state);
      break;
    default:
      SKYEYE_DBG ("io_write_word(0x%08x) = 0x%08x\n", addr, data);
      break;
    }
}

static void
at91rm92_io_write_byte (ARMul_State * state, ARMword addr, ARMword data)
{
  SKYEYE_DBG ("SKYEYE: at91rm92_io_write_byte error\n");
  at91rm92_io_write_word (state, addr, data);
}

static void
at91rm92_io_write_halfword (ARMul_State * state, ARMword addr, ARMword data)
{
  SKYEYE_DBG ("SKYEYE: at91rm92_io_write_halfword error\n");
  at91rm92_io_write_word (state, addr, data);
}


void
at91rm92_mach_init (ARMul_State * state, machine_config_t * this_mach)
{
  ARMul_SelectProcessor (state, ARM_v4_Prop);
  /* ARM920T uses LOW */
  state->lateabtSig = LOW;

  state->Reg[1] = 251;		//for AT91RM9200
  state->Reg[1] = 262;		//for AT91RM9200DK
  this_mach->mach_io_do_cycle = at91rm92_io_do_cycle;
  this_mach->mach_io_reset = at91rm92_io_reset;
  this_mach->mach_io_read_byte = at91rm92_io_read_byte;
  this_mach->mach_io_write_byte = at91rm92_io_write_byte;
  this_mach->mach_io_read_halfword = at91rm92_io_read_halfword;
  this_mach->mach_io_write_halfword = at91rm92_io_write_halfword;
  this_mach->mach_io_read_word = at91rm92_io_read_word;
  this_mach->mach_io_write_word = at91rm92_io_write_word;

  this_mach->mach_update_int = at91rm92_update_int;

  //this_mach->mach_set_intr =              at91rm92_set_intr;
  //this_mach->mach_pending_intr =          at91rm92_pending_intr;
  //this_mach->mach_update_intr =           at91rm92_update_intr;

  //this_mach->mach_mem_read_byte =       at91rm92_mem_read_byte;
  //this_mach->mach_mem_write_byte =      at91rm92_mem_write_byte;

  //this_mach->state = (void *)state;


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -