📄 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>//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------/*struct timeval{ int tv_sec; int tv_usec;};*///AJ2D--------------------------------------------------------------------------#endif/* 2007-01-18 added by Anthony Lee : for new uart device frame */#include "skyeye_uart.h"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 & 0x1static voids3c44b0_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 voids3c44b0_set_interrupt (unsigned int irq){ /*if (ENABLE_IRQ){ io.i_ispr = (1 << interrupt); } */ if (ENABLE_IRQ | ENABLE_FIQ) { io.intpnd |= (1 << irq); }}static voids3c44b0_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 inttimer_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. * */staticget_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*/voids3c44b0_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)) { /* 2007-01-18 modified by Anthony Lee : for new uart device frame */ struct timeval tv; unsigned char buf; tv.tv_sec = 0; tv.tv_usec = 0; if(skyeye_uart_read(-1, &buf, 1, &tv, NULL) > 0) { 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 * */ARMwords3c44b0_io_read_byte (ARMul_State * state, ARMword addr){ s3c44b0_io_read_word (state, addr); /*printf("SKYEYE: s3c44b0_io_read_byte error\n"); exit(-1); */}ARMwords3c44b0_io_read_halfword (ARMul_State * state, ARMword addr){ s3c44b0_io_read_word (state, addr); /*printf("SKYEYE: s3c44b0_io_read_halfword error\n"); exit(-1); */}ARMwords3c44b0_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 * */voids3c44b0_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); */}voids3c44b0_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"); skyeye_exit (-1);}voids3c44b0_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; /* 2007-01-18 modified by Anthony Lee : for new uart device frame */ skyeye_uart_write(-1, &c, 1, NULL); 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; }}voids3c44b0_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; /* 2007-01-28 : added by Anthony Lee */ this_mach->state = (void *) state;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -