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

📄 skyeye_mach_s3c44b0x.c

📁 skyeye for pxa270
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	io.rtc_offset = (long int)mktime(curr_tm) - (long int)curr_time.tv_sec;exit:	return;}/* DMA Routine */static void s3c44b0x_dma_proccess(ARMul_State *state, int index){	int i = index;	int dal, das, dst, opt_tdm;	s3c44b0x_dma_read_func read_func;	s3c44b0x_dma_write_func write_func;	ARMword ccnt, src_addr, dst_addr, data;	ccnt = DMA_CCNT(io.dma[i]);	if ((ccnt & 0xfffff) == 0x0) {		if ((ccnt & 0x200000) == 0x0) return;		memcpy(&io.dma[i][4], &io.dma[i][1], 3 * sizeof(ARMword)); /* auto-reload */		DMA_CON(io.dma[i]) &= ~0x30;		DMA_CCNT(io.dma[i]) &= ~0x3000000;		return;	}	src_addr = DMA_CSRC(io.dma[i]);	dst_addr = DMA_CDES(io.dma[i]);	if ((dal = ((src_addr >> 28) & 0x3)) == 0x0) return;	if ((das = ((dst_addr >> 28) & 0x3)) == 0x0) return;	if ((dst = ((src_addr >> 30) & 0x3)) == 0x3) return;	if (i < 2 && dst != 0x2 && ((ccnt >> 26) & 0x3) == 0x2) return;	if ((opt_tdm = ((dst_addr >> 30) & 0x3)) == 0x0 && i >= 2) return;	if ((ccnt & 0xfffff) >= (1 << dst)) {		read_func = dma_read_funcs[i < 2 ? dst : (3 + (dst * 3) + (opt_tdm - 1))];		write_func = dma_write_funcs[i < 2 ? dst : (3 + (dst * 3) + (opt_tdm - 1))];		if (((ccnt >> 26) & 0x3) != 0x3 || ((ccnt >> 24) & 0x3) != 0x2) { /* read */			data = (*read_func)(state, (src_addr & 0xfffffff));			if (i < 2 && dst != 0 && (opt_tdm & 0x1) != 0x0) /* swap */				data = (dst == 1 ? HALFWORD_SWAP(data) : WORD_SWAP(data));			if (dal == 1) src_addr += min(0xfffffff - (src_addr & 0xfffffff), 1 << dst);			else if (dal == 2) src_addr -= min((src_addr & 0xfffffff), 1 << dst);			DMA_CSRC(io.dma[i]) = src_addr;		}		if (((ccnt >> 26) & 0x3) != 0x3 || ((ccnt >> 24) & 0x3) == 0x2) { /* write */			if (((ccnt >> 26) & 0x3) == 0x3) data = DMA_FLY(io.dma[i]);			(*write_func)(state, (dst_addr & 0xfffffff), data);			if (das == 1) dst_addr += min(0xfffffff - (dst_addr & 0xfffffff), 1 << dst);			else if (das == 2) dst_addr -= min((dst_addr & 0xfffffff), 1 << dst);			DMA_CDES(io.dma[i]) = dst_addr;		}		if (((ccnt >> 26) & 0x3) == 0x3) { /* on-the-fly mode */			if (((ccnt >> 24) & 0x3) != 0x2) {				DMA_FLY(io.dma[i]) = data;				ccnt &= ~0x3000000;				ccnt |= 0x2000000; /* Read time */			} else {				ccnt |= 0x3000000; /* Write time */			}		}	}	if ((ccnt & 0xfffff) <= (1 << dst)) { /* terminated count */		ccnt &= ~0xfffff;		if ((ccnt & 0x200000) == 0x0) ccnt &= ~0x100000; /* clear EN bit */		DMA_CON(io.dma[i]) &= ~0x30;		DMA_CON(io.dma[i]) |= 0x20;		if (((ccnt >> 22) & 0x3) > 1) s3c44b0x_set_interrupt(INT_ZDMA0 - i);	} else {		ccnt -= (1 << dst);		if (((ccnt >> 22) & 0x3) == 2) s3c44b0x_set_interrupt(INT_ZDMA0 - i);	}	DMA_CCNT(io.dma[i]) = ccnt;}static int s3c44b0x_dma_is_valid(int index){	ARMword ccnt;	if ((DMA_CON(io.dma[index]) & 0xc) != 0x0) return -1;	if (((ccnt = DMA_CCNT(io.dma[index])) & 0x100000) == 0x0) return -1;	if (index < 2) { /* ZDMA */		if (((ccnt >> 30) & 0x3) < 0x2) return 1; /* DMA request, till now it's impossible in simulation */	} else { /* BDMA */		if (((ccnt >> 26) & 0x3) == 0x3) return -1; /* don't support on-the-fly mode */		if (((ccnt >> 30) & 0x3) != 0x0) return 1; /* DMA request */	}	return 0;}static void s3c44b0x_dma_do_cycle(ARMul_State *state){	int i;	for (i = 0; i < 4; i++) {		if (s3c44b0x_dma_is_valid(i) != 0) continue;		s3c44b0x_dma_proccess(state, i);	}}static void s3c44b0x_dma_read(ARMword addr, ARMword *data){	s3c44b0x_dma_t *dma = &io.dma[(addr & 0xff) / 0x20 + (addr <= ZDCCNT1 ? 0 : 2)];	ARMword *val = (ARMword*)dma + (((addr & 0xff) % 0x20) >> 2);	*data = *val;	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c44b0x_dma_write(ARMul_State *state, ARMword addr, ARMword data){	s3c44b0x_dma_t *dma = &io.dma[(addr & 0xff) / 0x20 + (addr <= ZDCCNT1 ? 0 : 2)];	ARMword *val = (ARMword*)dma + (((addr & 0xff) % 0x20) >> 2);	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);	if ((addr & 0xff) % 0x20 == 0x00) { /* CON */		*val = ((*val & 0x30) | (data & ~0x33));		if ((data & 0x3) == 0x3) DMA_CSRC((*dma)) &= ~0x100000; /* clear EN bit */		return;	} else if ((addr & 0xff) % 0x20 < 0x10) { /* ISRC, IDES, ICNT */		*val = data;		*(val + 3) = data;		return;	}	PRINT("ERROR: %s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);}/* IIS Routine */static int s3c44b0x_iis_write_to_device(ARMul_State *state, ARMhword *buf, int count){	ARMword data;	if (buf != s3c44b0x_iisfifo_tx) memcpy(s3c44b0x_iisfifo_tx, buf, count * 2);	io_write_word(state, IISFIF_TX_CONTROL, ((0xa << 8) | (0x1 << 4) | count));#if 0	data = io_read_word(state, IISFIF_TX_CONTROL);	if ((data & 0xff0) != 0xa20) return -1;	return (int)(data & 0xf);#else	/* don't care */	return count;#endif}static int s3c44b0x_iis_read_from_device(ARMul_State *state, ARMhword *data){	ARMword tmp;	tmp = io_read_word(state, IISFIF_RX_CONTROL);	if (((tmp >> 16) & 0xff) != 0x15) return -1;	*data = (ARMhword)(tmp & 0xffff);	return 0;}static void s3c44b0x_iis_do_cycle(ARMul_State *state){	int count;	if ((io.iiscon & 0x1) == 0) return;	while (((io.iismod >> 7) & 0x1) && (io.iisfifcon & 0x2f0) > 0x200) { /* handling TX FIFO */		int nWritten = -1;		if (io.iisfifo_txcnt > 0) {			io.iisfifo_txcnt -= 1;			break;		}		count = (io.iisfifcon >> 4) & 0xf;		nWritten = s3c44b0x_iis_write_to_device(state, &io.iisfifo_tx[0], count);		if (nWritten <= 0) break;		count -= nWritten;		io.iisfifcon = ((io.iisfifcon & ~0xf0) | (count << 4));		if (count == 0) {			io.iiscon &= ~0x80;			io.iisfifo_txcnt = 8;		} else {			memmove(&io.iisfifo_tx[0], &io.iisfifo_tx[nWritten], count * 2);		}		break;	}	while (((io.iismod >> 6) & 0x1) && ((io.iisfifcon >> 8) & 0x1)) { /* handling RX FIFO */		ARMhword tmp;		if ((count = io.iisfifcon & 0xf) >= 8) break;		if (s3c44b0x_iis_read_from_device(state, &tmp) != 0) break;		io.iisfifo_rx[count++] = tmp;		io.iisfifcon = ((io.iisfifcon & ~0xf) | count);		if (count == 8) io.iiscon &= ~0x40;		break;	}	while ((io.iiscon & 0x30) != 0) { /* BDMA request */		int rx_empty = ((io.iisfifcon & 0x100) ? ((io.iisfifcon & 0xf) == 0) : 0);		int tx_ready = ((io.iisfifcon & 0x100) ? (((io.iisfifcon >> 4) & 0xf) < 8) : 1);		ARMword mask = 0;		if (s3c44b0x_dma_is_valid(2) != 1) break;		if (((DMA_CCNT(io.dma[2]) >> 30) & 0x3) != 0x1) break;		if ((DMA_CDES(io.dma[2]) & 0xfffffff) == IISFIF + state->bigendSig * 2 && tx_ready) mask |= (0x1 << 5);		if ((DMA_CSRC(io.dma[2]) & 0xfffffff) == IISFIF + state->bigendSig * 2 && !rx_empty) mask |= (0x1 << 4);		if ((io.iiscon & mask) != 0) s3c44b0x_dma_proccess(state, 2);		break;	}}static void s3c44b0x_iis_read(ARMul_State *state, ARMword addr, ARMword *data){	switch (addr) {		case IISCON:			*data = io.iiscon;			break;		case IISMOD:			*data = io.iismod;			break;		case IISPSR:			*data = io.iispsr;			break;		case IISFIFCON:			*data = io.iisfifcon;			break;		case IISFIF:			if (!((io.iiscon & 0x1) && ((io.iismod >> 6) & 0x1))) break;			if ((io.iisfifcon & 0x100) != 0) { /* FIFO */				int count = (io.iisfifcon & 0xf);				if (count > 0) {					*data = io.iisfifo_rx[0];					io.iisfifcon = ((io.iisfifcon & ~0xf) | (--count));					if (count > 0) memmove(&io.iisfifo_rx[0], &io.iisfifo_rx[1], count * 2);					io.iiscon |= 0x40;				}			} else { /* non FIFO */				ARMhword tmp;				if (s3c44b0x_iis_read_from_device(state, &tmp) == 0) *data = tmp;			}			break;		default:			break;	}	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, *data);}static void s3c44b0x_iis_write(ARMul_State *state, ARMword addr, ARMword data){	ARMhword tmp, count;	DEBUG("%s(addr:0x%x, data:0x%x)\n", __FUNCTION__, addr, data);	switch (addr) {		case IISCON:			io.iiscon = ((io.iiscon & 0x1c0) | (data & ~0x1c0));			break;		case IISMOD:			io.iismod  = data;			break;		case IISPSR:			io.iispsr = data;			break;		case IISFIFCON:			io.iisfifcon = ((io.iisfifcon & 0xff) | (data & ~0xff));			break;		case IISFIF:			if (!((io.iiscon & 0x1) && ((io.iismod >> 7) & 0x1))) break;			tmp = data & 0xffff;			if ((io.iisfifcon & 0x200) != 0) { /* FIFO */				if ((count = ((io.iisfifcon >> 4) & 0xf)) < 8) {					io.iisfifo_tx[count++] = tmp;					io.iisfifcon = ((io.iisfifcon & ~0xf0) | (count << 4));					io.iiscon |= 0x80;				}			} else { /* non FIFO */				s3c44b0x_iis_write_to_device(state, &tmp, 1);			}			break;		default:			break;	}}/* IO Read Routine */static ARMword s3c44b0x_io_read_word(ARMul_State *state, ARMword addr){	ARMword data = -1;	/* Interrupt */	if (addr >= INTCON && addr <= F_ISPC) {		s3c44b0x_interrupt_read(addr, &data);		return data;	}	/* UART */	if (addr >= ULCON0 && addr <= UBRDIV1) {		s3c44b0x_uart_read(addr, &data);		return data;	}	/* Timer */	if ((addr >= WTCON && addr <= WTCNT) || (addr >= TCFG0 && addr <= TCNTO5)) {		s3c44b0x_timer_read(addr, &data);		return data;	}	/* I/O Ports */	if (addr >= PCONA && addr <= EXTINTPND) {		s3c44b0x_ports_read(addr, &data);		return data;	}	/* RTC */	if (addr >= RTCCON && addr <= TICINT) {		s3c44b0x_rtc_read(addr, &data);		return data;	}	/* DMA */	if ((addr >= ZDCON0 && addr <= ZDCCNT1) || (addr >= BDCON0 && addr <= BDCCNT1)) {		s3c44b0x_dma_read(addr, &data);		return data;	}	/* IIS */	if (addr >= IISCON && addr <= IISFIF) {		s3c44b0x_iis_read(state, addr, &data);		return data;	}	/* TODO */	switch (addr) {		case SYSCFG:			data = 0x01; /* FIXME */			break;		case NCACHBE0:			data = io.ncachbe0;			break;		case NCACHBE1:			data = io.ncachbe1;			break;		case SBUSCON:			data = io.sbuscon;			break;		case BWSCON:			data = io.bwscon;			break;		default:			DEBUG("UNIMPLEMENTED: %s(addr:0x%08x)\n", __FUNCTION__, addr);			break;	}	return data;}static ARMword s3c44b0x_io_read_byte(ARMul_State *state, ARMword addr){	ARMword data, offset;	data = s3c44b0x_io_read_word(state, (addr & ~0x3));	/* bit offset into the word */	offset = ((state->bigendSig * 3) ^ (addr & 3)) << 3;	return ((data >> offset) & 0xff);}static ARMword s3c44b0x_io_read_halfword(ARMul_State *state, ARMword addr){	ARMword data, offset;	data = s3c44b0x_io_read_word(state, addr & ~0x3);	/* bit offset into the word */	offset = ((state->bigendSig * 2) ^ (addr & 2)) << 3;	return ((data >> offset) & 0xffff);}/* IO Write Routine */static void s3c44b0x_io_write_word(ARMul_State *state, ARMword addr, ARMword data){	/* Interrupt */	if (addr >= INTCON && addr <= F_ISPC) {		s3c44b0x_interrupt_write(state, addr, data);		return;	}	/* UART */	if (addr >= ULCON0 && addr <= UBRDIV1) {		s3c44b0x_uart_write(state, addr, data);		return;	}	/* Timer */	if ((addr >= WTCON && addr <= WTCNT) || (addr >= TCFG0 && addr <= TCNTO5)) {		s3c44b0x_timer_write(state, addr, data);		return;	}	/* I/O Ports */	if (addr >= PCONA && addr <= EXTINTPND) {		s3c44b0x_ports_write(state, addr, data);		return;	}	/* RTC */	if (addr >= RTCCON && addr <= TICINT) {		s3c44b0x_rtc_write(state, addr, data);		return;	}	/* DMA */	if ((addr >= ZDCON0 && addr <= ZDCCNT1) || (addr >= BDCON0 && addr <= BDCCNT1)) {		s3c44b0x_dma_write(state, addr, data);		return;	}	/* IIS */	if (addr >= IISCON && addr <= IISFIF) {		s3c44b0x_iis_write(state, addr, data);		return;	}	/* TODO */	switch (addr) {		case SYSCFG:			io.syscfg = data;			break;		case NCACHBE0:			io.ncachbe0 = data;			break;		case NCACHBE1:			io.ncachbe1 = data;			break;		case SBUSCON:			io.sbuscon = data;			break;		case BWSCON:			io.bwscon = (io.bwscon & 0x1) | (data & ~0x1);			break;		default:			DEBUG("UNIMPLEMENTED: %s(addr:0x%08x, data:0x%x)\n", __FUNCTION__, addr, data);			break;	}}static void s3c44b0x_io_write_byte(ARMul_State *state, ARMword addr, ARMword data){	if ((state->bigendSig * 3) == (addr & 3)) {		s3c44b0x_io_write_word(state, addr & ~0x3, data);		return;	}	DEBUG("ERROR: %s(addr:0x%08x, data:0x%x)\n", __FUNCTION__, addr, data);}static void s3c44b0x_io_write_halfword(ARMul_State *state, ARMword addr, ARMword data){	if ((state->bigendSig * 2) == (addr & 3)) {		s3c44b0x_io_write_word(state, addr & ~0x3, data);		return;	}	DEBUG("ERROR: %s(addr:0x%08x, data:0x%x)\n", __FUNCTION__, addr, data);}static void s3c44b0x_io_do_cycle(ARMul_State *state){	/* TODO */	s3c44b0x_uart_do_cycle(state);	s3c44b0x_timer_do_cycle(state);	s3c44b0x_rtc_do_cycle(state);	s3c44b0x_dma_do_cycle(state);	s3c44b0x_iis_do_cycle(state);	s3c44b0x_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))#define MACH_IO_SET_INTR_FUNC(f)	((void (*)(u32))(f))#define MACH_IO_PENDING_INTR_FUNC(f)	((int (*)(u32))(f))#define MACH_IO_UPDATE_INTR_FUNC(f)	((void (*)(void*))(f))void s3c44b0x_mach_init(ARMul_State *state, machine_config_t *this_mach){	ARMul_SelectProcessor(state, ARM_v4_Prop);	state->lateabtSig = HIGH;	state->Reg[1] = 178; /* R1: machine type : found in linux-2.6.x/include/asm/mach-types.h */	this_mach->mach_io_do_cycle = MACH_IO_DO_CYCLE_FUNC(s3c44b0x_io_do_cycle);	this_mach->mach_io_reset = MACH_IO_RESET_FUNC(s3c44b0x_io_reset);	this_mach->mach_io_read_word = MACH_IO_READ_FUNC(s3c44b0x_io_read_word);	this_mach->mach_io_read_halfword = MACH_IO_READ_FUNC(s3c44b0x_io_read_halfword);	this_mach->mach_io_read_byte = MACH_IO_READ_FUNC(s3c44b0x_io_read_byte);	this_mach->mach_io_write_word = MACH_IO_WRITE_FUNC(s3c44b0x_io_write_word);	this_mach->mach_io_write_halfword = MACH_IO_WRITE_FUNC(s3c44b0x_io_write_halfword);	this_mach->mach_io_write_byte = MACH_IO_WRITE_FUNC(s3c44b0x_io_write_byte);	this_mach->mach_update_int = MACH_IO_UPDATE_INT_FUNC(s3c44b0x_update_int);	/* mach_set_intr, mach_pending_intr, mach_update_intr, state : for devices, such as NET,LCD etc. */	this_mach->mach_set_intr = MACH_IO_SET_INTR_FUNC(s3c44b0x_set_interrupt);	this_mach->mach_pending_intr = MACH_IO_PENDING_INTR_FUNC(s3c44b0x_pending_intr);	this_mach->mach_update_intr = MACH_IO_UPDATE_INTR_FUNC(s3c44b0x_update_intr);	this_mach->state = (void*)state;}

⌨️ 快捷键说明

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