📄 skyeye_mach_ep7312.c
字号:
/*
skyeye_mach_ep7312.c - define machine ep7312 for skyeye
Copyright (C) 2003 Skyeye Develop Group
for help please send mail to <skyeye-developer@lists.sf.linuxforum.net>
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
*/
/*
* 3/24/2003 init this file.
* add machine ep7312's function. Most taken from original armio.c.
* include: ep7312_mach_init, ep7312_io_do_cycle
* ep7312_io_read_word, ep7312_io_write_word
* walimis <walimi@peoplemail.com.cn>
*
* */
#include "armdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "clps7110.h"
//zzc:
#ifdef __CYGWIN__
//chy 2005-07-28
#include <time.h>
struct timeval
{
long tv_sec;
long tv_usec;
};
#endif
//ywc 2004-04-01
extern unsigned long Pen_buffer[8]; // defined in skyeye_lcd.c
#define DEBUG 1
#if DEBUG
#define DBG_PRINT(a...) fprintf(stderr,##a)
#else
#define DBG_PRINT(a...)
#endif
/*Internal IO Register*/
typedef struct ep7312_io
{
ARMword syscon; /* System control */
ARMword sysflg; /* System status flags */
ARMword intsr; /* Interrupt status reg */
ARMword intmr; /* Interrupt mask reg */
ARMword tcd[2]; /* Timer/counter data */
ARMword tcd_reload[2]; /* Last value written */
ARMword uartdr; /* Receive data register */
//ywc,2004-04-01
ARMword ts_int; /* ywc 2004-04-02 */
ARMword ts_buffer[8];
//ARMword tsaddr; /* ??? touch srceen data buffer start address*/
ARMword ts_addr_begin;
ARMword ts_addr_end;
//2004-06-21
ARMword padr;
ARMword pbdr;
ARMword pddr;
ARMword paddr;
ARMword pbddr;
ARMword pdddr;
ARMword pedr;
ARMword peddr;
} ep7312_io_t;
static ep7312_io_t ep7312_io;
#define io ep7312_io
static void
ep7312_update_int (ARMul_State * state)
{
ARMword requests = io.intsr & io.intmr;
state->NfiqSig = (requests & 0x0001) ? LOW : HIGH;
state->NirqSig = (requests & 0xfffe) ? LOW : HIGH;
}
static void
ep7312_io_reset (ARMul_State * state)
{
io.syscon = LCDEN;
io.sysflg = URXFE;
io.intmr = 0;
io.intsr = UTXINT; /* always ready to transmit */
io.tcd[0] = 0xffff;
io.tcd[1] = 0xffff;
io.tcd_reload[0] = 0xffff;
io.tcd_reload[1] = 0xffff;
io.uartdr = 0;
//ywc 2004-04-01
//io.tsaddr =0x0;
io.ts_int = EINT2; /* ywc 2004-04-02 use EINT2 as touch screen interrupt */
io.ts_addr_begin = 0x8000b000;
io.ts_addr_end = 0x8000b01f;
//state->Exception = TRUE;
}
void
ep7312_io_do_cycle (ARMul_State * state)
{
int t;
for (t = 0; t < 2; t++)
{
if (io.tcd[t] == 0)
{
if (io.syscon & (t ? TC2M : TC1M))
{
io.tcd[t] = io.tcd_reload[t];
}
else
{
io.tcd[t] = 0xffff;
}
io.intsr |= (t ? TC2OI : TC1OI);
ep7312_update_int (state);
}
else
{
io.tcd[t]--;
}
}
if (!(io.intsr & URXINT))
{
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.uartdr = (int) buf;
io.sysflg &= ~URXFE;
io.intsr |= URXINT;
ep7312_update_int (state);
}
}
} //if (!(io.intsr & URXINT))
// ywc 2004-04-01 for touch screen interrupt
#ifndef NO_LCD
{
if (!(io.intsr & io.ts_int))
{ //if now has no ts interrupt,then query
if (Pen_buffer[6] == 1)
{ //should trigger a interrupt
*(io.ts_buffer + 0) = Pen_buffer[0];
*(io.ts_buffer + 1) = Pen_buffer[1];
*(io.ts_buffer + 4) = Pen_buffer[4];
*(io.ts_buffer + 6) = Pen_buffer[6];
//set EINT2 bit to trigger a interrupt,ts driver will clear it
io.intsr |= io.ts_int;
Pen_buffer[6] = 0;
}
}
}
#endif
}
ARMword
ep7312_io_read_byte (ARMul_State * state, ARMword addr)
{
ARMword data = -1;
unsigned char offset = 0;
unsigned char ret;
switch (addr - 0x80000000)
{
case PADR:
data = io.padr;
break;
case PBDR:
data = io.pbdr;
break;
case PDDR:
data = io.pddr;
break;
case PADDR:
data = io.paddr;
break;
case PBDDR:
data = io.pbddr;
break;
case PDDDR:
data = io.pdddr;
break;
case PEDR:
data = io.pedr;
break;
case PEDDR:
data = io.peddr;
break;
default:
printf ("SKYEYE: ep7312_io_read_byte error\n");
printf ("SKYEYE: state->pc=%x,state->instr=%x,addr=%x\n",
state->pc, state->instr, addr);
exit (-1);
break;
}
return data;
}
ARMword
ep7312_io_read_halfword (ARMul_State * state, ARMword addr)
{
printf ("SKYEYE: ep7312_io_read_halfword error\n");
exit (-1);
}
ARMword
ep7312_io_read_word (ARMul_State * state, ARMword addr)
{
ARMword data = 0;
ARMword ts_addr;
//ywc 2004-04-01 read the touch srceen data buffer,return to the ts device driver
ts_addr = addr & ~3; // 1 word==4 byte
if (ts_addr >= io.ts_addr_begin && ts_addr <= io.ts_addr_end)
{
data = io.ts_buffer[(ts_addr - io.ts_addr_begin) / 4];
return data;
}
switch (addr - 0x80000000)
{
case SYSCON:
data = io.syscon;
break;
case SYSFLG:
data = io.sysflg;
break;
/* case MEMCFG1:
* case MEMCFG2:
* case DRFPR */
case INTSR:
data = io.intsr;
break;
case INTMR:
data = io.intmr;
break;
case TC1D:
data = io.tcd[0];
break;
case TC2D:
data = io.tcd[1];
break;
/* case RTCDR:
* case RTCMR:
* case PMPCON :
* case CODR:*/
case UARTDR:
data = io.uartdr;
io.sysflg |= URXFE;
io.intsr &= ~URXINT;
ep7312_update_int (state);
break;
/* case UBRLCR: */
case SYNCIO:
/* if we return zero here, the battery voltage calculation
* results in a divide-by-zero that messes up the kernel */
data = 1;
break;
/* case PALLSW:
* case PALMSW:*/
/* write-only: */
case STFCLR:
case BLEOI:
case MCEOI:
case TEOI:
case TC1EOI:
case TC2EOI:
case RTCEOI:
case UMSEOI:
case COEOI:
case HALT:
case STDBY:
break;
default:
//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
//SKYEYE_DBG("io_read_word(0x%08x) = 0x%08x\n", addr, data);
break;
}
return data;
}
void
ep7312_io_write_byte (ARMul_State * state, ARMword addr, ARMword data)
{
//fprintf(stderr,"skyeye:ep7312_io_write_byte,@addr is %x",addr);
unsigned char offset = 0;
unsigned char ret;
switch (addr - 0x80000000)
{
case PADR:
io.padr = data;
break;
case PBDR:
io.pbdr = data;
break;
case PDDR:
io.pddr = data;
break;
case PADDR:
io.paddr = data;
break;
case PBDDR:
io.pbddr = data;
break;
case PDDDR:
io.pdddr = data;
break;
case PEDR:
data = io.pedr;
break;
case PEDDR:
io.peddr = data;
break;
default:
printf ("SKYEYE: ep7312_io_write_byte error@@@@@@@\n");
SKYEYE_OUTREGS (stderr);
exit (-1);
break;
}
}
void
ep7312_io_write_halfword (ARMul_State * state, ARMword addr, ARMword data)
{
printf ("SKYEYE: ep7312_io_write_halfword error\n");
exit (-1);
}
void
ep7312_io_write_word (ARMul_State * state, ARMword addr, ARMword data)
{
ARMword tmp;
switch (addr - 0x80000000)
{
case SYSCON:
tmp = io.syscon;
io.syscon = data;
//chy 2004-03-11
if ((tmp & LCDEN) != (data & LCDEN))
{
// by ywc 2004-07-07
printf ("\n\n SYSCON:will call ep7312_update_lcd()");
//ep7312_update_lcd (state);
}
break;
case SYSFLG:
break;
case INTSR:
//DBG_PRINT("write INTSR=0x%x\n", data);
io.intsr = data;
// printf("SKYEYE: write INTSR=0x%x\n", io.intsr);
break;
case INTMR:
//DBG_PRINT("write INTMR=0x%x\n", data);
//if(data != 0x2000 && data != 0x2200)
//printf("SKYEYE: write INTMR=0x%x\n", data);
io.intmr = data;
ep7312_update_int (state);
break;
case TC1D:
io.tcd[0] = io.tcd_reload[0] = data & 0xffff;
SKYEYE_DBG ("TC1D 0x%x\n", data & 0xffff);
break;
case TC2D:
io.tcd[1] = io.tcd_reload[1] = data & 0xffff;
SKYEYE_DBG ("TC2D 0x%x\n", data & 0xffff);
break;
case UARTDR:
/* The UART writes chars to console */
{
char c = data;
write (skyeye_config.uart.fd_out, &c, 1);
}
break;
/* case BLEOI: printf("BLEOI\n"); break;
case MCEOI: printf("MCEOI\n"); break;
case TEOI: printf("TEOI\n"); break;*/
case TC1EOI:
io.intsr &= ~TC1OI;
ep7312_update_int (state);
SKYEYE_DBG ("TC1EOI\n");
break;
case TC2EOI:
io.intsr &= ~TC2OI;
ep7312_update_int (state);
SKYEYE_DBG ("TC2EOI\n");
break;
//case RTCEOI: printf("RTCEOI\n"); break;
//case UMSEOI: printf("UMSEOI\n"); break;
//case COEOI: printf("COEOI\n"); break;
case 0x2000:
/* Not a real register, for debugging only: */
SKYEYE_DBG ("io_write_word debug: 0x%08lx\n", data);
break;
default:
//chy 2003-07-11: sometime has fault, but linux can continue running !!!!????
//printf("SKYEYE:unknown io addr, io_write_word(0x%08x, 0x%08x), pc %x \n", addr, data,state->Reg[15]);
break;
}
}
void
ep7312_mach_init (ARMul_State * state, machine_config_t * this_mach)
{
state->abort_model = 2;
//chy 2003-08-19, setprocessor
ARMul_SelectProcessor (state, ARM_v4_Prop);
//chy 2004-05-09, set lateabtSig
state->lateabtSig = HIGH;
state->Reg[1] = 91; //for EP7212/EP7312 arch id
this_mach->mach_io_do_cycle = ep7312_io_do_cycle;
this_mach->mach_io_reset = ep7312_io_reset;
this_mach->mach_io_read_byte = ep7312_io_read_byte;
this_mach->mach_io_write_byte = ep7312_io_write_byte;
this_mach->mach_io_read_halfword = ep7312_io_read_halfword;
this_mach->mach_io_write_halfword = ep7312_io_write_halfword;
this_mach->mach_io_read_word = ep7312_io_read_word;
this_mach->mach_io_write_word = ep7312_io_write_word;
this_mach->mach_update_int = ep7312_update_int;
this_mach->state = (void *) state;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -