📄 skyeye_mach_s3c2410x.c
字号:
/* skyeye_mach_s3c2410x.c - define machine S3C2410X for skyeye Copyright (C) 2005 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 */#include "armdefs.h"#include "s3c2410x.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"typedef struct s3c2410_memctl_s{ uint32_t bwscon; uint32_t bankcon[8]; uint32_t refresh; uint32_t banksize; uint32_t mrsrb6; uint32_t mrsrb7;}s3c2410_memctl_t;typedef struct s3c2410_wd_timer_s{ uint32_t wtcon; uint32_t wtdat; uint32_t wtcnt;}s3c2410_wd_timer_t;typedef struct s3c2410x_io{ u32 srcpnd; /* Indicate the interrupt request status */ u32 intmod; /* Interrupt mode register */ u32 intmsk; /* Determine which interrupt source is masked */ u32 priority; /* IRQ priority control register */ u32 intpnd; /* Indicate the interrupt request status */ u32 intoffset; /* Indicate the IRQ interrupt request source */ u32 subsrcpnd; /* Indicate the interrupt request status */ u32 intsubmsk; /* Determin which interrupt source is masked */ u32 eintmask; /* Interrupt pending register for 20 external interrupts (EINT[23:4]) */ u32 eintpend; /* Interrupt mask register for 20 external interrupts (EINT[23:4]). */ struct s3c2410x_timer_io timer; /* Timer */ struct s3c2410x_uart_io uart[3]; /* uart */ struct s3c2410x_clkpower clkpower; /* clock and power management */ s3c2410_memctl_t memctl; s3c2410_wd_timer_t wd_timer; uint32_t gpio_ctl[0xc0]; /* GPIO control register */} s3c2410x_io_t;static s3c2410x_io_t s3c2410x_io;#define io s3c2410x_iostatic inline voids3c2410x_set_subsrcint (unsigned int irq){ io.subsrcpnd |= irq;}static inline voids3c2410x_update_subsrcint (){ u32 requests; s3c2410x_set_subsrcint (UART_INT_TXD << (0 * 3)); s3c2410x_set_subsrcint (UART_INT_TXD << (1 * 3)); s3c2410x_set_subsrcint (UART_INT_TXD << (2 * 3)); requests = ((io.subsrcpnd & (~io.intsubmsk)) & 0x7fff); if (requests & 0x7) io.srcpnd |= INT_UART0; if (requests & 0x38) io.srcpnd |= INT_UART1; if (requests & 0x1c0) io.srcpnd |= INT_UART2; if (requests & 0x600) io.srcpnd |= INT_ADC;}static inline voids3c2410x_update_extint (){ u32 requests = ((io.eintpend & (~io.eintmask))); if (requests & 0xF0) io.srcpnd |= INT_EINT4_7; if (requests & 0xFFFF00) io.srcpnd |= INT_EINT8_23;}static voids3c2410x_update_int (ARMul_State * state){ ARMword requests; s3c2410x_update_subsrcint (); s3c2410x_update_extint (); requests = io.srcpnd & (~io.intmsk & INT_MASK_INIT); state->NfiqSig = (requests & io.intmod) ? LOW : HIGH; state->NirqSig = (requests & ~io.intmod) ? LOW : HIGH;}static voids3c2410x_set_ext_intr (u32 interrupt){ io.eintpend |= (1 << interrupt);}static ints3c2410x_pending_ext_intr (u32 interrupt){ return ((io.eintpend & (1 << interrupt)));}static voids3c2410x_update_intr (void *mach){ struct machine_config *mc = (struct machine_config *) mach; ARMul_State *state = (ARMul_State *) mc->state; s3c2410x_update_int (state);}static voids3c2410x_io_reset (ARMul_State * state){ int i; memset (&s3c2410x_io, 0, sizeof (s3c2410x_io)); for (i = 0; i < 3; i++) { io.uart[i].ulcon = UART_ULCON_INIT; io.uart[i].utrstat = UART_UTRSTAT_INIT; } //io.timer.tcnt[4] = 25350; io.clkpower.locktime = 0x00FFFFFF; //io.clkpower.mpllcon = 0x00070022; /* That is a value mizi required */ io.clkpower.mpllcon = 0x0002c080; /* workaround for linux-2.6.10 by ksh */ io.clkpower.upllcon = 0x00028080; io.clkpower.clkcon = 0x7FFF0; io.clkpower.clkslow = 0x4; io.intmsk = INT_MASK_INIT; io.intpnd = 0x0; io.eintmask = 0x00FFFFF0; /* ARM920T uses LOW */ state->lateabtSig = LOW; state->Reg[1] = 193; //for SMDK2410 //state->Reg[1] = 395; //for SMDK2410TK //state->Reg[1] = 241; //ARCH_S3C2440}/* s3c2410x io_do_cycle */static voids3c2410x_io_do_cycle (ARMul_State * state){ int i; if ((io.timer.tcon & 0x100000) != 0) { io.timer.tcnt[4]--; if (io.timer.tcnt[4] < 0) { io.timer.tcnt[4] = io.timer.tcntb[4]; /*timer 4 hasn't tcmp */ //io.timer.tcmp[4] = io.timer.tcmpb[4]; io.timer.tcnto[4] = io.timer.tcntb[4]; io.srcpnd |= INT_TIMER4; s3c2410x_update_int (state); return; } } for (i = 0; i < 3; i++) { if (((io.uart[i].utrstat & 0x1) == 0x0) && ((io.uart[i].ucon & 0x3) == 0x1)) { struct timeval tv; unsigned char buf; tv.tv_sec = 0; tv.tv_usec = 0; if (skyeye_uart_read(i, &buf, 1, &tv, NULL) > 0) { /* convert ctrl+c to ctrl+a. */ if (buf == 1) buf = 3; io.uart[i].urxh = buf; /* Receiver Ready * */ io.uart[i].utrstat |= (0x1); io.uart[i].ufstat |= (0x1); /* 2007-02-09 by Anthony Lee : for 1 bytes */ /* pending usart0 interrupt * */ s3c2410x_set_subsrcint (UART_INT_RXD << (i * 3)); //io.srcpnd |= INT_UART0; s3c2410x_update_int (state); } } } //s3c2410x_update_int (state);}static voids3c2410x_uart_read (u32 offset, u32 * data, int index){ switch (offset) { case ULCON: *data = io.uart[index].ulcon; break; case UCON: *data = io.uart[index].ucon; break; case UFCON: *data = io.uart[index].ufcon; break; case UMCON: *data = io.uart[index].umcon; break; case UTRSTAT: *data = io.uart[index].utrstat; break; case UERSTAT: *data = io.uart[index].uerstat; break; case UFSTAT: *data = io.uart[index].ufstat; break; case UMSTAT: *data = io.uart[index].umstat; break; case URXH: /* receive char * */ *data = io.uart[index].urxh; io.uart[index].utrstat &= (~0x1); /* clear strstat register bit[0] */ io.uart[index].ufstat &= ~(0x1); /* 2007-02-09 by Anthony Lee : for 0 bytes */ break; case UBRDIV: *data = io.uart[index].ubrdiv; break; default: break; } SKYEYE_DBG ("%s(UART%d: 0x%x, 0x%x)\n", __FUNCTION__, index, offset, data);}static voids3c2410x_uart_write (ARMul_State * state, u32 offset, u32 data, int index){ SKYEYE_DBG ("%s(UART%d: 0x%x, 0x%x)\n", __FUNCTION__, index, offset, data); switch (offset) { case ULCON: io.uart[index].ulcon = data; break; case UCON: io.uart[index].ucon = data; break; case UFCON: io.uart[index].ufcon = data; break; case UMCON: io.uart[index].umcon = data; break; case UTRSTAT: io.uart[index].utrstat = data; break; case UERSTAT: io.uart[index].uerstat = data; break; case UFSTAT: io.uart[index].ufstat = data; break; case UMSTAT: io.uart[index].umstat = data; break; case UTXH: { char c = data; /* 2007-01-18 modified by Anthony Lee : for new uart device frame */ skyeye_uart_write(index, &c, 1, NULL); io.uart[index].utrstat |= 0x6; //set strstat register bit[0] if ((io.uart[index].ucon & 0xc) == 0x4) { s3c2410x_set_subsrcint (UART_INT_TXD << (index * 3)); s3c2410x_update_int (state); } } break; case UBRDIV: io.uart[index].ubrdiv = data; break; default: break; }}static voids3c2410x_timer_read (u32 offset, u32 * data){ switch (offset) { case TCFG0: *data = io.timer.tcfg0; break; case TCFG1: *data = io.timer.tcfg1; break; case TCON: *data = io.timer.tcon; break; case TCNTB0: case TCNTB1: case TCNTB2: case TCNTB3: case TCNTB4: { int n = (offset - 0xC) / 0xC; *data = io.timer.tcntb[n]; } break; case TCMPB0: case TCMPB1: case TCMPB2: case TCMPB3: { int n = (offset - 0x10) / 0xC; *data = io.timer.tcmpb[n]; } break; case TCNTO0: case TCNTO1: case TCNTO2: case TCNTO3: { int n = (offset - 0x10) / 0xC; *data = io.timer.tcnto[n]; } break; case TCNTO4: *data = io.timer.tcnt[4]; break; default: break; }}static voids3c2410x_timer_write (ARMul_State * state, u32 offset, u32 data){ switch (offset) { case TCFG0: io.timer.tcfg0 = data; break; case TCFG1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -