mirror of
				https://git.proxmox.com/git/qemu
				synced 2025-10-31 18:49:42 +00:00 
			
		
		
		
	MusicPal qdev conversion
Signed-off-by: Paul Brook <paul@codesourcery.com>
This commit is contained in:
		
							parent
							
								
									fe7e8758d0
								
							
						
					
					
						commit
						b47b50fa9e
					
				
							
								
								
									
										150
									
								
								hw/musicpal.c
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								hw/musicpal.c
									
									
									
									
									
								
							| @ -6,7 +6,7 @@ | ||||
|  * This code is licenced under the GNU GPL v2. | ||||
|  */ | ||||
| 
 | ||||
| #include "hw.h" | ||||
| #include "sysbus.h" | ||||
| #include "arm-misc.h" | ||||
| #include "devices.h" | ||||
| #include "net.h" | ||||
| @ -57,7 +57,8 @@ | ||||
| #define MP_FLASH_SIZE_MAX       32*1024*1024 | ||||
| 
 | ||||
| #define MP_TIMER1_IRQ           4 | ||||
| /* ... */ | ||||
| #define MP_TIMER2_IRQ           5 | ||||
| #define MP_TIMER3_IRQ           6 | ||||
| #define MP_TIMER4_IRQ           7 | ||||
| #define MP_EHCI_IRQ             8 | ||||
| #define MP_ETH_IRQ              9 | ||||
| @ -525,6 +526,7 @@ typedef struct mv88w8618_rx_desc { | ||||
| } mv88w8618_rx_desc; | ||||
| 
 | ||||
| typedef struct mv88w8618_eth_state { | ||||
|     SysBusDevice busdev; | ||||
|     qemu_irq irq; | ||||
|     uint32_t smir; | ||||
|     uint32_t icr; | ||||
| @ -748,20 +750,17 @@ static void eth_cleanup(VLANClientState *vc) | ||||
|     qemu_free(s); | ||||
| } | ||||
| 
 | ||||
| static void mv88w8618_eth_init(NICInfo *nd, uint32_t base, qemu_irq irq) | ||||
| static void mv88w8618_eth_init(SysBusDevice *dev) | ||||
| { | ||||
|     mv88w8618_eth_state *s; | ||||
|     mv88w8618_eth_state *s = FROM_SYSBUS(mv88w8618_eth_state, dev); | ||||
| 
 | ||||
|     qemu_check_nic_model(nd, "mv88w8618"); | ||||
| 
 | ||||
|     s = qemu_mallocz(sizeof(mv88w8618_eth_state)); | ||||
|     s->irq = irq; | ||||
|     s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, | ||||
|     sysbus_init_irq(dev, &s->irq); | ||||
|     s->vc = qdev_get_vlan_client(&dev->qdev, | ||||
|                                  eth_receive, eth_can_receive, | ||||
|                                  eth_cleanup, s); | ||||
|     s->mmio_index = cpu_register_io_memory(0, mv88w8618_eth_readfn, | ||||
|                                            mv88w8618_eth_writefn, s); | ||||
|     cpu_register_physical_memory(base, MP_ETH_SIZE, s->mmio_index); | ||||
|     sysbus_init_mmio(dev, MP_ETH_SIZE, s->mmio_index); | ||||
| } | ||||
| 
 | ||||
| /* LCD register offsets */ | ||||
| @ -784,6 +783,7 @@ static void mv88w8618_eth_init(NICInfo *nd, uint32_t base, qemu_irq irq) | ||||
| #define MP_LCD_TEXTCOLOR        0xe0e0ff /* RRGGBB */ | ||||
| 
 | ||||
| typedef struct musicpal_lcd_state { | ||||
|     SysBusDevice busdev; | ||||
|     uint32_t mode; | ||||
|     uint32_t irqctrl; | ||||
|     int page; | ||||
| @ -943,14 +943,14 @@ static CPUWriteMemoryFunc *musicpal_lcd_writefn[] = { | ||||
|     musicpal_lcd_write | ||||
| }; | ||||
| 
 | ||||
| static void musicpal_lcd_init(void) | ||||
| static void musicpal_lcd_init(SysBusDevice *dev) | ||||
| { | ||||
|     musicpal_lcd_state *s; | ||||
|     musicpal_lcd_state *s = FROM_SYSBUS(musicpal_lcd_state, dev); | ||||
|     int iomemtype; | ||||
| 
 | ||||
|     s = qemu_mallocz(sizeof(musicpal_lcd_state)); | ||||
|     iomemtype = cpu_register_io_memory(0, musicpal_lcd_readfn, | ||||
|                                        musicpal_lcd_writefn, s); | ||||
|     sysbus_init_mmio(dev, MP_LCD_SIZE, iomemtype); | ||||
|     cpu_register_physical_memory(MP_LCD_BASE, MP_LCD_SIZE, iomemtype); | ||||
| 
 | ||||
|     s->ds = graphic_console_init(lcd_refresh, lcd_invalidate, | ||||
| @ -965,6 +965,7 @@ static void musicpal_lcd_init(void) | ||||
| 
 | ||||
| typedef struct mv88w8618_pic_state | ||||
| { | ||||
|     SysBusDevice busdev; | ||||
|     uint32_t level; | ||||
|     uint32_t enabled; | ||||
|     qemu_irq parent_irq; | ||||
| @ -1037,22 +1038,18 @@ static CPUWriteMemoryFunc *mv88w8618_pic_writefn[] = { | ||||
|     mv88w8618_pic_write | ||||
| }; | ||||
| 
 | ||||
| static qemu_irq *mv88w8618_pic_init(uint32_t base, qemu_irq parent_irq) | ||||
| static void mv88w8618_pic_init(SysBusDevice *dev) | ||||
| { | ||||
|     mv88w8618_pic_state *s; | ||||
|     mv88w8618_pic_state *s = FROM_SYSBUS(mv88w8618_pic_state, dev); | ||||
|     int iomemtype; | ||||
|     qemu_irq *qi; | ||||
| 
 | ||||
|     s = qemu_mallocz(sizeof(mv88w8618_pic_state)); | ||||
|     qi = qemu_allocate_irqs(mv88w8618_pic_set_irq, s, 32); | ||||
|     s->parent_irq = parent_irq; | ||||
|     qdev_init_irq_sink(&dev->qdev, mv88w8618_pic_set_irq, 32); | ||||
|     sysbus_init_irq(dev, &s->parent_irq); | ||||
|     iomemtype = cpu_register_io_memory(0, mv88w8618_pic_readfn, | ||||
|                                        mv88w8618_pic_writefn, s); | ||||
|     cpu_register_physical_memory(base, MP_PIC_SIZE, iomemtype); | ||||
|     sysbus_init_mmio(dev, MP_PIC_SIZE, iomemtype); | ||||
| 
 | ||||
|     qemu_register_reset(mv88w8618_pic_reset, s); | ||||
| 
 | ||||
|     return qi; | ||||
| } | ||||
| 
 | ||||
| /* PIT register offsets */ | ||||
| @ -1069,14 +1066,15 @@ static qemu_irq *mv88w8618_pic_init(uint32_t base, qemu_irq parent_irq) | ||||
| #define MP_BOARD_RESET_MAGIC    0x10000 | ||||
| 
 | ||||
| typedef struct mv88w8618_timer_state { | ||||
|     ptimer_state *timer; | ||||
|     ptimer_state *ptimer; | ||||
|     uint32_t limit; | ||||
|     int freq; | ||||
|     qemu_irq irq; | ||||
| } mv88w8618_timer_state; | ||||
| 
 | ||||
| typedef struct mv88w8618_pit_state { | ||||
|     void *timer[4]; | ||||
|     SysBusDevice busdev; | ||||
|     mv88w8618_timer_state timer[4]; | ||||
|     uint32_t control; | ||||
| } mv88w8618_pit_state; | ||||
| 
 | ||||
| @ -1087,19 +1085,16 @@ static void mv88w8618_timer_tick(void *opaque) | ||||
|     qemu_irq_raise(s->irq); | ||||
| } | ||||
| 
 | ||||
| static void *mv88w8618_timer_init(uint32_t freq, qemu_irq irq) | ||||
| static void mv88w8618_timer_init(SysBusDevice *dev, mv88w8618_timer_state *s, | ||||
|                                  uint32_t freq) | ||||
| { | ||||
|     mv88w8618_timer_state *s; | ||||
|     QEMUBH *bh; | ||||
| 
 | ||||
|     s = qemu_mallocz(sizeof(mv88w8618_timer_state)); | ||||
|     s->irq = irq; | ||||
|     sysbus_init_irq(dev, &s->irq); | ||||
|     s->freq = freq; | ||||
| 
 | ||||
|     bh = qemu_bh_new(mv88w8618_timer_tick, s); | ||||
|     s->timer = ptimer_init(bh); | ||||
| 
 | ||||
|     return s; | ||||
|     s->ptimer = ptimer_init(bh); | ||||
| } | ||||
| 
 | ||||
| static uint32_t mv88w8618_pit_read(void *opaque, target_phys_addr_t offset) | ||||
| @ -1109,8 +1104,8 @@ static uint32_t mv88w8618_pit_read(void *opaque, target_phys_addr_t offset) | ||||
| 
 | ||||
|     switch (offset) { | ||||
|     case MP_PIT_TIMER1_VALUE ... MP_PIT_TIMER4_VALUE: | ||||
|         t = s->timer[(offset-MP_PIT_TIMER1_VALUE) >> 2]; | ||||
|         return ptimer_get_count(t->timer); | ||||
|         t = &s->timer[(offset-MP_PIT_TIMER1_VALUE) >> 2]; | ||||
|         return ptimer_get_count(t->ptimer); | ||||
| 
 | ||||
|     default: | ||||
|         return 0; | ||||
| @ -1126,18 +1121,18 @@ static void mv88w8618_pit_write(void *opaque, target_phys_addr_t offset, | ||||
| 
 | ||||
|     switch (offset) { | ||||
|     case MP_PIT_TIMER1_LENGTH ... MP_PIT_TIMER4_LENGTH: | ||||
|         t = s->timer[offset >> 2]; | ||||
|         t = &s->timer[offset >> 2]; | ||||
|         t->limit = value; | ||||
|         ptimer_set_limit(t->timer, t->limit, 1); | ||||
|         ptimer_set_limit(t->ptimer, t->limit, 1); | ||||
|         break; | ||||
| 
 | ||||
|     case MP_PIT_CONTROL: | ||||
|         for (i = 0; i < 4; i++) { | ||||
|             if (value & 0xf) { | ||||
|                 t = s->timer[i]; | ||||
|                 ptimer_set_limit(t->timer, t->limit, 0); | ||||
|                 ptimer_set_freq(t->timer, t->freq); | ||||
|                 ptimer_run(t->timer, 0); | ||||
|                 t = &s->timer[i]; | ||||
|                 ptimer_set_limit(t->ptimer, t->limit, 0); | ||||
|                 ptimer_set_freq(t->ptimer, t->freq); | ||||
|                 ptimer_run(t->ptimer, 0); | ||||
|             } | ||||
|             value >>= 4; | ||||
|         } | ||||
| @ -1162,29 +1157,28 @@ static CPUWriteMemoryFunc *mv88w8618_pit_writefn[] = { | ||||
|     mv88w8618_pit_write | ||||
| }; | ||||
| 
 | ||||
| static void mv88w8618_pit_init(uint32_t base, qemu_irq *pic, int irq) | ||||
| static void mv88w8618_pit_init(SysBusDevice *dev) | ||||
| { | ||||
|     int iomemtype; | ||||
|     mv88w8618_pit_state *s; | ||||
| 
 | ||||
|     s = qemu_mallocz(sizeof(mv88w8618_pit_state)); | ||||
|     mv88w8618_pit_state *s = FROM_SYSBUS(mv88w8618_pit_state, dev); | ||||
|     int i; | ||||
| 
 | ||||
|     /* Letting them all run at 1 MHz is likely just a pragmatic
 | ||||
|      * simplification. */ | ||||
|     s->timer[0] = mv88w8618_timer_init(1000000, pic[irq]); | ||||
|     s->timer[1] = mv88w8618_timer_init(1000000, pic[irq + 1]); | ||||
|     s->timer[2] = mv88w8618_timer_init(1000000, pic[irq + 2]); | ||||
|     s->timer[3] = mv88w8618_timer_init(1000000, pic[irq + 3]); | ||||
|     for (i = 0; i < 4; i++) { | ||||
|         mv88w8618_timer_init(dev, &s->timer[i], 1000000); | ||||
|     } | ||||
| 
 | ||||
|     iomemtype = cpu_register_io_memory(0, mv88w8618_pit_readfn, | ||||
|                                        mv88w8618_pit_writefn, s); | ||||
|     cpu_register_physical_memory(base, MP_PIT_SIZE, iomemtype); | ||||
|     sysbus_init_mmio(dev, MP_PIT_SIZE, iomemtype); | ||||
| } | ||||
| 
 | ||||
| /* Flash config register offsets */ | ||||
| #define MP_FLASHCFG_CFGR0    0x04 | ||||
| 
 | ||||
| typedef struct mv88w8618_flashcfg_state { | ||||
|     SysBusDevice busdev; | ||||
|     uint32_t cfgr0; | ||||
| } mv88w8618_flashcfg_state; | ||||
| 
 | ||||
| @ -1226,17 +1220,15 @@ static CPUWriteMemoryFunc *mv88w8618_flashcfg_writefn[] = { | ||||
|     mv88w8618_flashcfg_write | ||||
| }; | ||||
| 
 | ||||
| static void mv88w8618_flashcfg_init(uint32_t base) | ||||
| static void mv88w8618_flashcfg_init(SysBusDevice *dev) | ||||
| { | ||||
|     int iomemtype; | ||||
|     mv88w8618_flashcfg_state *s; | ||||
| 
 | ||||
|     s = qemu_mallocz(sizeof(mv88w8618_flashcfg_state)); | ||||
|     mv88w8618_flashcfg_state *s = FROM_SYSBUS(mv88w8618_flashcfg_state, dev); | ||||
| 
 | ||||
|     s->cfgr0 = 0xfffe4285; /* Default as set by U-Boot for 8 MB flash */ | ||||
|     iomemtype = cpu_register_io_memory(0, mv88w8618_flashcfg_readfn, | ||||
|                        mv88w8618_flashcfg_writefn, s); | ||||
|     cpu_register_physical_memory(base, MP_FLASHCFG_SIZE, iomemtype); | ||||
|     sysbus_init_mmio(dev, MP_FLASHCFG_SIZE, iomemtype); | ||||
| } | ||||
| 
 | ||||
| /* Misc register offsets */ | ||||
| @ -1317,13 +1309,13 @@ static CPUWriteMemoryFunc *mv88w8618_wlan_writefn[] = { | ||||
|     mv88w8618_wlan_write, | ||||
| }; | ||||
| 
 | ||||
| static void mv88w8618_wlan_init(uint32_t base) | ||||
| static void mv88w8618_wlan_init(SysBusDevice *dev) | ||||
| { | ||||
|     int iomemtype; | ||||
| 
 | ||||
|     iomemtype = cpu_register_io_memory(0, mv88w8618_wlan_readfn, | ||||
|                                        mv88w8618_wlan_writefn, NULL); | ||||
|     cpu_register_physical_memory(base, MP_WLAN_SIZE, iomemtype); | ||||
|     sysbus_init_mmio(dev, MP_WLAN_SIZE, iomemtype); | ||||
| } | ||||
| 
 | ||||
| /* GPIO register offsets */ | ||||
| @ -1518,7 +1510,10 @@ static void musicpal_init(ram_addr_t ram_size, | ||||
|                const char *initrd_filename, const char *cpu_model) | ||||
| { | ||||
|     CPUState *env; | ||||
|     qemu_irq *pic; | ||||
|     qemu_irq *cpu_pic; | ||||
|     qemu_irq pic[32]; | ||||
|     DeviceState *dev; | ||||
|     int i; | ||||
|     int index; | ||||
|     unsigned long flash_size; | ||||
| 
 | ||||
| @ -1530,7 +1525,7 @@ static void musicpal_init(ram_addr_t ram_size, | ||||
|         fprintf(stderr, "Unable to find CPU definition\n"); | ||||
|         exit(1); | ||||
|     } | ||||
|     pic = arm_pic_init_cpu(env); | ||||
|     cpu_pic = arm_pic_init_cpu(env); | ||||
| 
 | ||||
|     /* For now we use a fixed - the original - RAM size */ | ||||
|     cpu_register_physical_memory(0, MP_RAM_DEFAULT_SIZE, | ||||
| @ -1539,8 +1534,14 @@ static void musicpal_init(ram_addr_t ram_size, | ||||
|     sram_off = qemu_ram_alloc(MP_SRAM_SIZE); | ||||
|     cpu_register_physical_memory(MP_SRAM_BASE, MP_SRAM_SIZE, sram_off); | ||||
| 
 | ||||
|     pic = mv88w8618_pic_init(MP_PIC_BASE, pic[ARM_PIC_CPU_IRQ]); | ||||
|     mv88w8618_pit_init(MP_PIT_BASE, pic, MP_TIMER1_IRQ); | ||||
|     dev = sysbus_create_simple("mv88w8618_pic", MP_PIC_BASE, | ||||
|                                cpu_pic[ARM_PIC_CPU_IRQ]); | ||||
|     for (i = 0; i < 32; i++) { | ||||
|         pic[i] = qdev_get_irq_sink(dev, i); | ||||
|     } | ||||
|     sysbus_create_varargs("mv88w8618_pit", MP_PIT_BASE, pic[MP_TIMER1_IRQ], | ||||
|                           pic[MP_TIMER2_IRQ], pic[MP_TIMER3_IRQ], | ||||
|                           pic[MP_TIMER4_IRQ], NULL); | ||||
| 
 | ||||
|     if (serial_hds[0]) | ||||
|         serial_mm_init(MP_UART1_BASE, 2, pic[MP_UART1_IRQ], 1825000, | ||||
| @ -1571,17 +1572,22 @@ static void musicpal_init(ram_addr_t ram_size, | ||||
|                               2, 0x00BF, 0x236D, 0x0000, 0x0000, | ||||
|                               0x5555, 0x2AAA); | ||||
|     } | ||||
|     mv88w8618_flashcfg_init(MP_FLASHCFG_BASE); | ||||
|     sysbus_create_simple("mv88w8618_flashcfg", MP_FLASHCFG_BASE, NULL); | ||||
| 
 | ||||
|     musicpal_lcd_init(); | ||||
|     sysbus_create_simple("musicpal_lcd", MP_LCD_BASE, NULL); | ||||
| 
 | ||||
|     qemu_add_kbd_event_handler(musicpal_key_event, pic[MP_GPIO_IRQ]); | ||||
| 
 | ||||
|     mv88w8618_eth_init(&nd_table[0], MP_ETH_BASE, pic[MP_ETH_IRQ]); | ||||
|     qemu_check_nic_model(&nd_table[0], "mv88w8618"); | ||||
|     dev = qdev_create(NULL, "mv88w8618_eth"); | ||||
|     qdev_set_netdev(dev, &nd_table[0]); | ||||
|     qdev_init(dev); | ||||
|     sysbus_mmio_map(sysbus_from_qdev(dev), 0, MP_ETH_BASE); | ||||
|     sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[MP_ETH_IRQ]); | ||||
| 
 | ||||
|     mixer_i2c = musicpal_audio_init(pic[MP_AUDIO_IRQ]); | ||||
| 
 | ||||
|     mv88w8618_wlan_init(MP_WLAN_BASE); | ||||
|     sysbus_create_simple("mv88w8618_wlan", MP_WLAN_BASE, NULL); | ||||
| 
 | ||||
|     musicpal_misc_init(); | ||||
|     musicpal_gpio_init(); | ||||
| @ -1598,3 +1604,21 @@ QEMUMachine musicpal_machine = { | ||||
|     .desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)", | ||||
|     .init = musicpal_init, | ||||
| }; | ||||
| 
 | ||||
| static void musicpal_register_devices(void) | ||||
| { | ||||
|     sysbus_register_dev("mv88w8618_pic", sizeof(mv88w8618_pic_state), | ||||
|                         mv88w8618_pic_init); | ||||
|     sysbus_register_dev("mv88w8618_pit", sizeof(mv88w8618_pit_state), | ||||
|                         mv88w8618_pit_init); | ||||
|     sysbus_register_dev("mv88w8618_flashcfg", sizeof(mv88w8618_flashcfg_state), | ||||
|                         mv88w8618_flashcfg_init); | ||||
|     sysbus_register_dev("mv88w8618_eth", sizeof(mv88w8618_eth_state), | ||||
|                         mv88w8618_eth_init); | ||||
|     sysbus_register_dev("mv88w8618_wlan", sizeof(SysBusDevice), | ||||
|                         mv88w8618_wlan_init); | ||||
|     sysbus_register_dev("musicpal_lcd", sizeof(musicpal_lcd_state), | ||||
|                         musicpal_lcd_init); | ||||
| } | ||||
| 
 | ||||
| device_init(musicpal_register_devices) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Paul Brook
						Paul Brook