Made the etrax timers and serial-ports base address relocatable. Use target_phys_addr_t instead of target_ulong.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4058 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									05ba7d5f34
								
							
						
					
					
						commit
						ca87d03b77
					
				
							
								
								
									
										18
									
								
								hw/etraxfs.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								hw/etraxfs.c
									
									
									
									
									
								
							| @ -35,10 +35,10 @@ static void main_cpu_reset(void *opaque) | ||||
| } | ||||
| 
 | ||||
| /* Init functions for different blocks.  */ | ||||
| extern qemu_irq *etraxfs_pic_init(CPUState *env, target_ulong base); | ||||
| /* TODO: Make these blocks relocate:able.  */ | ||||
| extern void etraxfs_timer_init(CPUState *env, qemu_irq *irqs); | ||||
| extern void etraxfs_ser_init(CPUState *env, qemu_irq *irqs); | ||||
| extern qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base); | ||||
| void etraxfs_timer_init(CPUState *env, qemu_irq *irqs,  | ||||
| 			target_phys_addr_t base); | ||||
| void etraxfs_ser_init(CPUState *env, qemu_irq *irqs, target_phys_addr_t base); | ||||
| 
 | ||||
| static | ||||
| void bareetraxfs_init (int ram_size, int vga_ram_size, | ||||
| @ -84,8 +84,14 @@ void bareetraxfs_init (int ram_size, int vga_ram_size, | ||||
| 			  4, 0x0000, 0x0000, 0x0000, 0x0000); | ||||
| 
 | ||||
|     pic = etraxfs_pic_init(env, 0xb001c000); | ||||
|     etraxfs_timer_init(env, pic); | ||||
|     etraxfs_ser_init(env, pic); | ||||
|     /* 2 timers.  */ | ||||
|     etraxfs_timer_init(env, pic, 0xb001e000); | ||||
|     etraxfs_timer_init(env, pic, 0xb005e000); | ||||
|     /* 4 serial ports.  */ | ||||
|     etraxfs_ser_init(env, pic, 0xb0026000); | ||||
|     etraxfs_ser_init(env, pic, 0xb0028000); | ||||
|     etraxfs_ser_init(env, pic, 0xb002a000); | ||||
|     etraxfs_ser_init(env, pic, 0xb002c000); | ||||
| 
 | ||||
|     kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); | ||||
|     /* magic for boot.  */ | ||||
|  | ||||
| @ -30,7 +30,7 @@ | ||||
| struct fs_pic_state_t | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	target_ulong base; | ||||
| 	target_phys_addr_t base; | ||||
| 
 | ||||
| 	uint32_t rw_mask; | ||||
| 	/* Active interrupt lines.  */ | ||||
| @ -186,7 +186,7 @@ static void etraxfs_pic_handler(void *opaque, int irq, int level) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| qemu_irq *etraxfs_pic_init(CPUState *env, target_ulong base) | ||||
| qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base) | ||||
| { | ||||
| 	struct fs_pic_state_t *fs; | ||||
| 	qemu_irq *pic; | ||||
|  | ||||
| @ -35,25 +35,20 @@ | ||||
| 
 | ||||
| static uint32_t ser_readb (void *opaque, target_phys_addr_t addr) | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	uint32_t r = 0; | ||||
| 
 | ||||
| 	env = opaque; | ||||
| 	D(CPUState *env = opaque); | ||||
| 	D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | ||||
| 	return r; | ||||
| 	return 0; | ||||
| } | ||||
| static uint32_t ser_readw (void *opaque, target_phys_addr_t addr) | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	uint32_t r = 0; | ||||
| 	env = opaque; | ||||
| 	D(CPUState *env = opaque); | ||||
| 	D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | ||||
| 	return r; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | ||||
| { | ||||
| 	CPUState *env = opaque; | ||||
| 	D(CPUState *env = opaque); | ||||
| 	uint32_t r = 0; | ||||
| 
 | ||||
| 	switch (addr & 0xfff) | ||||
| @ -75,21 +70,19 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr) | ||||
| static void | ||||
| ser_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	env = opaque; | ||||
| 	D(CPUState *env = opaque); | ||||
|  	D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | ||||
| } | ||||
| static void | ||||
| ser_writew (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	env = opaque; | ||||
| 	D(CPUState *env = opaque); | ||||
| 	D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | ||||
| } | ||||
| static void | ||||
| ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| { | ||||
| 	CPUState *env = opaque; | ||||
| 	D(CPUState *env = opaque); | ||||
| 
 | ||||
| 	switch (addr & 0xfff) | ||||
| 	{ | ||||
| @ -110,24 +103,20 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| } | ||||
| 
 | ||||
| static CPUReadMemoryFunc *ser_read[] = { | ||||
|     &ser_readb, | ||||
|     &ser_readw, | ||||
|     &ser_readl, | ||||
| 	&ser_readb, | ||||
| 	&ser_readw, | ||||
| 	&ser_readl, | ||||
| }; | ||||
| 
 | ||||
| static CPUWriteMemoryFunc *ser_write[] = { | ||||
|     &ser_writeb, | ||||
|     &ser_writew, | ||||
|     &ser_writel, | ||||
| 	&ser_writeb, | ||||
| 	&ser_writew, | ||||
| 	&ser_writel, | ||||
| }; | ||||
| 
 | ||||
| void etraxfs_ser_init(CPUState *env, qemu_irq *irqs) | ||||
| void etraxfs_ser_init(CPUState *env, qemu_irq *irqs, target_phys_addr_t base) | ||||
| { | ||||
| 	int ser_regs; | ||||
| 
 | ||||
| 	ser_regs = cpu_register_io_memory(0, ser_read, ser_write, env); | ||||
| 	cpu_register_physical_memory (0xb0026000, 0x3c, ser_regs); | ||||
| 	cpu_register_physical_memory (0xb0028000, 0x3c, ser_regs); | ||||
| 	cpu_register_physical_memory (0xb002a000, 0x3c, ser_regs); | ||||
| 	cpu_register_physical_memory (0xb002c000, 0x3c, ser_regs); | ||||
| 	cpu_register_physical_memory (base, 0x3c, ser_regs); | ||||
| } | ||||
|  | ||||
| @ -28,27 +28,28 @@ | ||||
| 
 | ||||
| #define D(x) | ||||
| 
 | ||||
| #define R_TIME 0xb001e038 | ||||
| #define RW_TMR0_DIV 0xb001e000 | ||||
| #define R_TMR0_DATA 0xb001e004 | ||||
| #define RW_TMR0_CTRL 0xb001e008 | ||||
| #define RW_TMR1_DIV 0xb001e010 | ||||
| #define R_TMR1_DATA 0xb001e014 | ||||
| #define RW_TMR1_CTRL 0xb001e018 | ||||
| 
 | ||||
| #define RW_WD_CTRL 0xb001e040 | ||||
| #define RW_INTR_MASK 0xb001e048 | ||||
| #define RW_ACK_INTR 0xb001e04c | ||||
| #define R_INTR 0xb001e050 | ||||
| #define R_MASKED_INTR 0xb001e054 | ||||
| #define RW_TMR0_DIV   0x00 | ||||
| #define R_TMR0_DATA   0x04 | ||||
| #define RW_TMR0_CTRL  0x08 | ||||
| #define RW_TMR1_DIV   0x10 | ||||
| #define R_TMR1_DATA   0x14 | ||||
| #define RW_TMR1_CTRL  0x18 | ||||
| #define R_TIME        0x38 | ||||
| #define RW_WD_CTRL    0x40 | ||||
| #define RW_INTR_MASK  0x48 | ||||
| #define RW_ACK_INTR   0x4c | ||||
| #define R_INTR        0x50 | ||||
| #define R_MASKED_INTR 0x54 | ||||
| 
 | ||||
| struct fs_timer_t { | ||||
| 	QEMUBH *bh; | ||||
| 	unsigned int limit; | ||||
| 	int scale; | ||||
| 	ptimer_state *ptimer; | ||||
| 	CPUState *env; | ||||
| 	qemu_irq *irq; | ||||
| 	target_phys_addr_t base; | ||||
| 
 | ||||
| 	QEMUBH *bh; | ||||
| 	ptimer_state *ptimer; | ||||
| 	unsigned int limit; | ||||
| 	int scale; | ||||
| 	uint32_t mask; | ||||
| 	struct timeval last; | ||||
| 
 | ||||
| @ -57,16 +58,6 @@ struct fs_timer_t { | ||||
| 	uint32_t r_intr; | ||||
| }; | ||||
| 
 | ||||
| static struct fs_timer_t timer[2]; | ||||
| 
 | ||||
| static inline int timer_index(target_phys_addr_t addr) | ||||
| { | ||||
| 	int t = 0; | ||||
| 	if (addr >= 0xb005e000) | ||||
| 		t = 1; | ||||
| 	return t; | ||||
| } | ||||
| 
 | ||||
| /* diff two timevals.  Return a single int in us. */ | ||||
| int diff_timeval_us(struct timeval *a, struct timeval *b) | ||||
| { | ||||
| @ -78,31 +69,23 @@ int diff_timeval_us(struct timeval *a, struct timeval *b) | ||||
|         return diff; | ||||
| } | ||||
| 
 | ||||
| static uint32_t timer_readb (void *opaque, target_phys_addr_t addr) | ||||
| static uint32_t timer_rinvalid (void *opaque, target_phys_addr_t addr) | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	uint32_t r = 0; | ||||
| 
 | ||||
| 	env = opaque; | ||||
| 	D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | ||||
| 	return r; | ||||
| } | ||||
| static uint32_t timer_readw (void *opaque, target_phys_addr_t addr) | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	uint32_t r = 0; | ||||
| 
 | ||||
| 	env = opaque; | ||||
| 	D(printf ("%s %x pc=%x\n", __func__, addr, env->pc)); | ||||
| 	return r; | ||||
| 	struct fs_timer_t *t = opaque; | ||||
| 	CPUState *env = t->env; | ||||
| 	cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n",  | ||||
| 		  addr, env->pc); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | ||||
| { | ||||
| 	CPUState *env = opaque; | ||||
| 	struct fs_timer_t *t = opaque; | ||||
| 	D(CPUState *env = t->env); | ||||
| 	uint32_t r = 0; | ||||
| 	int t = timer_index(addr); | ||||
| 
 | ||||
| 	/* Make addr relative to this instances base.  */ | ||||
| 	addr -= t->base; | ||||
| 	switch (addr) { | ||||
| 	case R_TMR0_DATA: | ||||
| 		break; | ||||
| @ -113,21 +96,21 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | ||||
| 	{ | ||||
| 		struct timeval now; | ||||
| 		gettimeofday(&now, NULL); | ||||
| 		if (!(timer[t].last.tv_sec == 0  | ||||
| 		      && timer[t].last.tv_usec == 0)) { | ||||
| 			r = diff_timeval_us(&now, &timer[t].last); | ||||
| 		if (!(t->last.tv_sec == 0  | ||||
| 		      && t->last.tv_usec == 0)) { | ||||
| 			r = diff_timeval_us(&now, &t->last); | ||||
| 			r *= 1000; /* convert to ns.  */ | ||||
| 			r++; /* make sure we increase for each call.  */ | ||||
| 		} | ||||
| 		timer[t].last = now; | ||||
| 		t->last = now; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	case RW_INTR_MASK: | ||||
| 		r = timer[t].rw_intr_mask; | ||||
| 		r = t->rw_intr_mask; | ||||
| 		break; | ||||
| 	case R_MASKED_INTR: | ||||
| 		r = timer[t].r_intr & timer[t].rw_intr_mask; | ||||
| 		r = t->r_intr & t->rw_intr_mask; | ||||
| 		break; | ||||
| 	default: | ||||
| 		D(printf ("%s %x p=%x\n", __func__, addr, env->pc)); | ||||
| @ -137,18 +120,12 @@ static uint32_t timer_readl (void *opaque, target_phys_addr_t addr) | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| timer_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| timer_winvalid (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	env = opaque; | ||||
| 	D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | ||||
| } | ||||
| static void | ||||
| timer_writew (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| { | ||||
| 	CPUState *env; | ||||
| 	env = opaque; | ||||
| 	D(printf ("%s %x %x pc=%x\n", __func__, addr, value, env->pc)); | ||||
| 	struct fs_timer_t *t = opaque; | ||||
| 	CPUState *env = t->env; | ||||
| 	cpu_abort(env, "Unsupported short access. reg=%x pc=%x.\n",  | ||||
| 		  addr, env->pc); | ||||
| } | ||||
| 
 | ||||
| static void write_ctrl(struct fs_timer_t *t, uint32_t v) | ||||
| @ -212,20 +189,22 @@ static void timer_ack_irq(struct fs_timer_t *t) | ||||
| static void | ||||
| timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| { | ||||
| 	CPUState *env = opaque; | ||||
| 	int t = timer_index(addr); | ||||
| 	struct fs_timer_t *t = opaque; | ||||
| 	CPUState *env = t->env; | ||||
| 
 | ||||
| 	D(printf ("%s %x %x pc=%x\n", | ||||
| 		__func__, addr, value, env->pc)); | ||||
| 	/* Make addr relative to this instances base.  */ | ||||
| 	addr -= t->base; | ||||
| 	switch (addr) | ||||
| 	{ | ||||
| 		case RW_TMR0_DIV: | ||||
| 			D(printf ("RW_TMR0_DIV=%x\n", value)); | ||||
| 			timer[t].limit = value; | ||||
| 			t->limit = value; | ||||
| 			break; | ||||
| 		case RW_TMR0_CTRL: | ||||
| 			D(printf ("RW_TMR0_CTRL=%x\n", value)); | ||||
| 			write_ctrl(&timer[t], value); | ||||
| 			write_ctrl(t, value); | ||||
| 			break; | ||||
| 		case RW_TMR1_DIV: | ||||
| 			D(printf ("RW_TMR1_DIV=%x\n", value)); | ||||
| @ -235,14 +214,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| 			break; | ||||
| 		case RW_INTR_MASK: | ||||
| 			D(printf ("RW_INTR_MASK=%x\n", value)); | ||||
| 			timer[t].rw_intr_mask = value; | ||||
| 			t->rw_intr_mask = value; | ||||
| 			break; | ||||
| 		case RW_WD_CTRL: | ||||
| 			D(printf ("RW_WD_CTRL=%x\n", value)); | ||||
| 			break; | ||||
| 		case RW_ACK_INTR: | ||||
| 			timer[t].r_intr &= ~value; | ||||
| 			timer_ack_irq(&timer[t]); | ||||
| 			t->r_intr &= ~value; | ||||
| 			timer_ack_irq(t); | ||||
| 			break; | ||||
| 		default: | ||||
| 			printf ("%s %x %x pc=%x\n", | ||||
| @ -252,14 +231,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value) | ||||
| } | ||||
| 
 | ||||
| static CPUReadMemoryFunc *timer_read[] = { | ||||
|     &timer_readb, | ||||
|     &timer_readw, | ||||
|     &timer_rinvalid, | ||||
|     &timer_rinvalid, | ||||
|     &timer_readl, | ||||
| }; | ||||
| 
 | ||||
| static CPUWriteMemoryFunc *timer_write[] = { | ||||
|     &timer_writeb, | ||||
|     &timer_writew, | ||||
|     &timer_winvalid, | ||||
|     &timer_winvalid, | ||||
|     &timer_writel, | ||||
| }; | ||||
| 
 | ||||
| @ -273,23 +252,23 @@ static void timer_irq(void *opaque) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void etraxfs_timer_init(CPUState *env, qemu_irq *irqs) | ||||
| void etraxfs_timer_init(CPUState *env, qemu_irq *irqs,  | ||||
| 			target_phys_addr_t base) | ||||
| { | ||||
| 	static struct fs_timer_t *t; | ||||
| 	int timer_regs; | ||||
| 
 | ||||
| 	timer[0].bh = qemu_bh_new(timer_irq, &timer[0]); | ||||
| 	timer[0].ptimer = ptimer_init(timer[0].bh); | ||||
| 	timer[0].irq = irqs + 26; | ||||
| 	timer[0].mask = 1; | ||||
| 	timer[0].env = env; | ||||
| 	t = qemu_mallocz(sizeof *t); | ||||
| 	if (!t) | ||||
| 		return; | ||||
| 
 | ||||
| 	timer[1].bh = qemu_bh_new(timer_irq, &timer[1]); | ||||
| 	timer[1].ptimer = ptimer_init(timer[1].bh); | ||||
| 	timer[1].irq = irqs + 26; | ||||
| 	timer[1].mask = 1; | ||||
| 	timer[1].env = env; | ||||
| 	t->bh = qemu_bh_new(timer_irq, t); | ||||
| 	t->ptimer = ptimer_init(t->bh); | ||||
| 	t->irq = irqs + 26; | ||||
| 	t->mask = 1; | ||||
| 	t->env = env; | ||||
| 	t->base = base; | ||||
| 
 | ||||
| 	timer_regs = cpu_register_io_memory(0, timer_read, timer_write, env); | ||||
| 	cpu_register_physical_memory (0xb001e000, 0x5c, timer_regs); | ||||
| 	cpu_register_physical_memory (0xb005e000, 0x5c, timer_regs); | ||||
| 	timer_regs = cpu_register_io_memory(0, timer_read, timer_write, t); | ||||
| 	cpu_register_physical_memory (base, 0x5c, timer_regs); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 edgar_igl
						edgar_igl