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

📄 skyeye_mach_s3c3410x.c

📁 skyeye的开源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			io.tf4 |= (((uint64_t)min(data, 0xff)) << (io.tfstat << 3));			io.tfstat += (io.tfstat < 7 ? 1 : 8);			break;		case 0xf: /* TFCON */			if (index == 4) {				io.tfcon = min((data & ~0x2), 0xff);				if (data & 0x2) io.tfstat = 0;				if (data & 0x1) {					io.tf4_repeat[1] = (1 << ((data >> 4) & 0x3)) - 1;					io.tf4_repeat[0] = io.tf4_repeat[1];				}			}			break;		default:			break;	}}/* UART Routine */static void s3c3410x_uart_do_cycle(ARMul_State *state){	int i;	unsigned char buf;	struct timeval tv;	tv.tv_sec = 0;	tv.tv_usec = 0;	if ((io.ustat & 0x20) == 0 && (io.ucon & 0x3) != 0) {		if (skyeye_uart_read(-1, &buf, 1, &tv, NULL) > 0) {			io.urxh = buf;			io.ustat |= 0x20;			io.ufstat = (io.ufstat & ~0x7) | 0x1;			if ((io.ucon & 0x3) == 0x1) s3c3410x_set_interrupt(INT_URX);		}	}	for (i = 0; i < 2; i++) { /* DMA request */		if ((io.ucon & 0x3) == 0x2 + i || (io.ucon & 0xc) == 0x8 + i) {			int rx_empty = ((io.ucon & 0x3) != 0x0 ? ((io.ustat & 0x20) == 0) : 1);			int tx_ready = ((io.ucon & 0xc) != 0x0 ? 1 : 0);			ARMword mask = 0;			do {				if (s3c3410x_dma_is_valid(i) != 1) break;				if (((io.dma[i].con >> 2) & 0x3) != 0x2) break;				if ((io.dma[i].dst == UTXH ||				     io.dma[i].dst == UTXH_HW ||				     io.dma[i].dst == UTXH_W) && tx_ready) mask |= 0x2 + i;				if ((io.dma[i].src == URXH ||				     io.dma[i].src == URXH_HW ||				     io.dma[i].src == URXH_W) && !rx_empty) mask |= 0x8 + i;				if ((io.ucon & mask) != 0) s3c3410x_dma_proccess(state, i);			} while (0);		}	}}static void s3c3410x_uart_read(ARMword addr, ARMword *data){	switch (addr) {		case ULCON:			*data = io.ulcon;			break;		case UCON:			*data = io.ucon;			break;		case USTAT:			*data = io.ustat;			break;		case UFCON:			*data = io.ufcon;			break;		case UFSTAT:			*data = io.ufstat;			break;		case URXH_W:		case URXH_HW:		case URXH:			*data = io.urxh;			io.ustat &= ~0x20;			io.ufstat &= ~0x7;			break;		case UBRDIV:			*data = io.ubrdiv;			break;		default:			break;	}	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c3410x_uart_write(ARMul_State *state, ARMword addr, ARMword data){	int cnt = 0;	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);	switch (addr) {		case ULCON:			io.ulcon = data;			break;		case UCON:			io.ucon = data;			break;		case UFCON:			io.ufcon = data;			break;		case UTXH_W:			cnt = 4;			break;		case UTXH_HW:			cnt = 2;			break;		case UTXH:			cnt = 1;			break;		case UBRDIV:			io.ubrdiv = data;			break;		default:			break;	}	if (cnt > 0 && (io.ucon & 0xc)) {		do {			char tmp = data & 0xff;			data >>= 8;			skyeye_uart_write(-1, (void*)&tmp, 1, NULL);		} while (--cnt > 0);		if ((io.ucon & 0xc) == 0x4) s3c3410x_set_interrupt(INT_UTX);	}}/* DMA Routine */static int s3c3410x_dma_is_valid(int index){	if (!(io.dma[index].con & 0x1)) return -1;	if (io.dma[index].cnt == 0) return -1;	if (((io.dma[index].con >> 2) & 0x3) == 0x1) return -1;	if (((io.dma[index].con >> 2) & 0x3) != 0x0) return 1;	return 0;}static void s3c3410x_dma_proccess(ARMul_State *state, int index){	ARMword data, bytes, n = 0;	if (io.dma[index].cnt == 0) return;	io.dma[index].con |= 0x2;restart:	switch ((bytes = (1 << ((io.dma[index].con >> 12) & 0x3)))) {		case 1:			data = mem_read_byte(state, io.dma[index].src);			mem_write_byte(state, io.dma[index].dst, data);			break;		case 2:			data = mem_read_halfword(state, io.dma[index].src);			mem_write_halfword(state, io.dma[index].dst, data);			break;		case 4:			data = mem_read_word(state, io.dma[index].src);			mem_write_word(state, io.dma[index].dst, data);			break;		default:			return;	}	if (!((io.dma[index].con >> 7) & 0x1)) {		if (((io.dma[index].con >> 5) & 0x1) && io.dma[index].src >= bytes)			io.dma[index].src -= bytes;		else if (io.dma[index].src <= 0xffffffe - bytes)			io.dma[index].src++;	}	if (!((io.dma[index].con >> 6) & 0x1)) {		if (((io.dma[index].con >> 4) & 0x1) && io.dma[index].dst >= bytes)			io.dma[index].dst -= bytes;		else if (io.dma[index].dst <= 0xffffffe - bytes)			io.dma[index].dst++;	}	if (((io.dma[index].con >> 9) & 0x1) && ++n < 4) goto restart;	io.dma[index].cnt -= 1;	if (io.dma[index].cnt != 0 && ((io.dma[index].con >> 14) & 0x1)) {		if (((io.dma[index].con >> 2) & 0x3) == 0x0) {			n = 0;			goto restart;		}	}	if (io.dma[index].cnt == 0) {		io.dma[index].con &= ~0x3;		s3c3410x_set_interrupt(INT_DMA0 + index);	}}static void s3c3410x_dma_do_cycle(ARMul_State *state){	int i;	for (i = 0; i < 2; i++) {		if (s3c3410x_dma_is_valid(i) != 0) continue;		s3c3410x_dma_proccess(state, i);	}}static void s3c3410x_dma_read(ARMword offset, ARMword *data, int index){	switch (offset) {		case 0x0: /* DMASRC */			*data = io.dma[index].src;			break;		case 0x4: /* DMADST */			*data = io.dma[index].dst;			break;		case 0x8: /* DMACNT */			*data = io.dma[index].cnt;			break;		case 0xc: /* DMACON */			*data = io.dma[index].con;			break;		default:			break;	}	DEBUG("%s(DMA%d, offset:0x%x, data:0x%x)\n", __FUNCTION__, index, offset, *data);}static void s3c3410x_dma_write(ARMul_State *state, ARMword offset, ARMword data, int index){	DEBUG("%s(DMA%d, offset:0x%x, data:0x%x)\n", __FUNCTION__, index, offset, data);	switch (offset) {		case 0x0: /* DMASRC */			io.dma[index].src = (data & 0xffffffe);			break;		case 0x4: /* DMADST */			io.dma[index].dst = (data & 0xffffffe);			break;		case 0x8: /* DMACNT */			io.dma[index].cnt = (data & 0x7ffffff);			break;		case 0xc: /* DMACON */			io.dma[index].con = (io.dma[index].con & 0x2) | (data & ~0x2);			if ((data & 0x1) == 0) { /* stop */				io.dma[index].con &= ~0x2;				if (data & 0x100) s3c3410x_set_interrupt(INT_DMA0 + index);			}			break;		default:			break;	}}/* IO Read Routine */static ARMword s3c3410x_io_read_word(ARMul_State *state, ARMword addr){	ARMword data = -1;	/* Interrupt */	if (addr >= INTMOD && addr <= INTPRI7) {		s3c3410x_interrupt_read(addr, &data);		return data;	}	/* Timer */	if (addr >= TDAT0 && addr <= TFW4) {		s3c3410x_timer_read(addr & 0xf, &data, (addr >> 4) & 0xf);		return data;	} else if (addr == BTCON) {		return (io.btcon & 0xffff);	} else if (addr == BTCNT) {		return io.btcnt;	}	/* UART */	if (addr >= ULCON && addr <= UBRDIV) {		s3c3410x_uart_read(addr, &data);		return data;	}	/* DMA */	if (addr >= DMASRC0 && addr <= DMACON1 && (addr & 0xfff) <= 0xc) {		s3c3410x_dma_read(addr & 0xf, &data, ((addr >> 12) & 0xf) - 3);		return data;	}	switch (addr) {		case SYSCFG:			data = io.syscfg;			break;		case SYSCON:			data = io.syscon;			break;		default:			DEBUG("UNIMPLEMENTED: %s(addr:0x%08x)\n", __FUNCTION__, addr);			break;	}	return data;}static ARMword s3c3410x_io_read_byte(ARMul_State *state, ARMword addr){	return s3c3410x_io_read_word(state, addr);}static ARMword s3c3410x_io_read_halfword(ARMul_State *state, ARMword addr){	return s3c3410x_io_read_word(state, addr);}/* IO Write Routine */static void s3c3410x_io_write_word(ARMul_State *state, ARMword addr, ARMword data){	/* Interrupt */	if (addr >= INTMOD && addr <= INTPRI7) {		s3c3410x_interrupt_write(state, addr, data);		return;	}	/* Timer */	if (addr >= TDAT0 && addr <= TFW4) {		s3c3410x_timer_write(state, addr & 0xf, data, (addr >> 4) & 0xf);		return;	} else if (addr == BTCON) {		io.btcon &= ~0xffff;		io.btcon |= (data & ~0x1ff03);		if (((data >> 8) & 0xff) == 0xa5) io.btcon &= ~0x10000;		else if ((data & 0x1) == 0) io.btcon |= ((data & 0xff00) | 0x10000);		if (data & 0x2) io.btcnt = 0;		return;	}	/* UART */	if (addr >= ULCON && addr <= UBRDIV) {		s3c3410x_uart_write(state, addr, data);		return;	}	/* DMA */	if (addr >= DMASRC0 && addr <= DMACON1 && (addr & 0xfff) <= 0xc) {		s3c3410x_dma_write(state, addr & 0xf, data, ((addr >> 12) & 0xf) - 3);		return;	}	switch (addr) {		case SYSCFG:			io.syscfg = data;			break;		case SYSCON:			io.syscon = data;			break;		default:			DEBUG("UNIMPLEMENTED: %s(addr:0x%08x, data:0x%x)\n", __FUNCTION__, addr, data);			break;	}}static void s3c3410x_io_write_byte(ARMul_State *state, ARMword addr, ARMword data){	s3c3410x_io_write_word(state, addr, data);}static void s3c3410x_io_write_halfword(ARMul_State *state, ARMword addr, ARMword data){	s3c3410x_io_write_word(state, addr, data);}static void s3c3410x_io_do_cycle(ARMul_State *state){	s3c3410x_timer_do_cycle(state);	s3c3410x_uart_do_cycle(state);	s3c3410x_dma_do_cycle(state);	s3c3410x_update_int(state);}/* Machine Initialization */#define MACH_IO_DO_CYCLE_FUNC(f)	((void (*)(void*))(f))#define MACH_IO_RESET_FUNC(f)		((void (*)(void*))(f))#define MACH_IO_READ_FUNC(f)		((uint32_t (*)(void*, uint32_t))(f))#define MACH_IO_WRITE_FUNC(f)		((void (*)(void*, uint32_t, uint32_t))(f))#define MACH_IO_UPDATE_INT_FUNC(f)	((void (*)(void*))(f))void s3c3410x_mach_init(ARMul_State *state, machine_config_t *this_mach){	if (state->bigendSig != HIGH) {		PRINT("*** ERROR: Only support big endian, maybe you need to use \"-b\" option !!!\n");		skyeye_exit(-1);	}	ARMul_SelectProcessor(state, ARM_v4_Prop);	state->lateabtSig = HIGH;	state->Reg[1] = 377;	this_mach->mach_io_do_cycle = MACH_IO_DO_CYCLE_FUNC(s3c3410x_io_do_cycle);	this_mach->mach_io_reset = MACH_IO_RESET_FUNC(s3c3410x_io_reset);	this_mach->mach_io_read_word = MACH_IO_READ_FUNC(s3c3410x_io_read_word);	this_mach->mach_io_read_halfword = MACH_IO_READ_FUNC(s3c3410x_io_read_halfword);	this_mach->mach_io_read_byte = MACH_IO_READ_FUNC(s3c3410x_io_read_byte);	this_mach->mach_io_write_word = MACH_IO_WRITE_FUNC(s3c3410x_io_write_word);	this_mach->mach_io_write_halfword = MACH_IO_WRITE_FUNC(s3c3410x_io_write_halfword);	this_mach->mach_io_write_byte = MACH_IO_WRITE_FUNC(s3c3410x_io_write_byte);	this_mach->mach_update_int = MACH_IO_UPDATE_INT_FUNC(s3c3410x_update_int);	this_mach->state = (void*)state;}

⌨️ 快捷键说明

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