mirror of
				https://github.com/qemu/qemu.git
				synced 2025-10-31 20:44:16 +00:00 
			
		
		
		
	 1eed09cb4a
			
		
	
	
		1eed09cb4a
		
	
	
	
	
		
			
			The parameter is always zero except when registering the three internal io regions (ROM, unassigned, notdirty). Remove the parameter to reduce the API's power, thus facilitating future change. Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
		
			
				
	
	
		
			216 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			216 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
 | |
|  *
 | |
|  * Copyright (c) 2006 Openedhand Ltd.
 | |
|  * Written by Andrzej Zaborowski <balrog@zabor.org>
 | |
|  *
 | |
|  * This code is licensed under the GPLv2.
 | |
|  */
 | |
| 
 | |
| #include "hw.h"
 | |
| #include "pcmcia.h"
 | |
| #include "pxa.h"
 | |
| 
 | |
| struct PXA2xxPCMCIAState {
 | |
|     PCMCIASocket slot;
 | |
|     PCMCIACardState *card;
 | |
| 
 | |
|     qemu_irq irq;
 | |
|     qemu_irq cd_irq;
 | |
| };
 | |
| 
 | |
| static uint32_t pxa2xx_pcmcia_common_read(void *opaque,
 | |
|                 target_phys_addr_t offset)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
| 
 | |
|     if (s->slot.attached) {
 | |
|         return s->card->common_read(s->card->state, offset);
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static void pxa2xx_pcmcia_common_write(void *opaque,
 | |
|                 target_phys_addr_t offset, uint32_t value)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
| 
 | |
|     if (s->slot.attached) {
 | |
|         s->card->common_write(s->card->state, offset, value);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
 | |
|                 target_phys_addr_t offset)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
| 
 | |
|     if (s->slot.attached) {
 | |
|         return s->card->attr_read(s->card->state, offset);
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static void pxa2xx_pcmcia_attr_write(void *opaque,
 | |
|                 target_phys_addr_t offset, uint32_t value)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
| 
 | |
|     if (s->slot.attached) {
 | |
|         s->card->attr_write(s->card->state, offset, value);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
 | |
|                 target_phys_addr_t offset)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
| 
 | |
|     if (s->slot.attached) {
 | |
|         return s->card->io_read(s->card->state, offset);
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static void pxa2xx_pcmcia_io_write(void *opaque,
 | |
|                 target_phys_addr_t offset, uint32_t value)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
| 
 | |
|     if (s->slot.attached) {
 | |
|         s->card->io_write(s->card->state, offset, value);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static CPUReadMemoryFunc *pxa2xx_pcmcia_common_readfn[] = {
 | |
|     pxa2xx_pcmcia_common_read,
 | |
|     pxa2xx_pcmcia_common_read,
 | |
|     pxa2xx_pcmcia_common_read,
 | |
| };
 | |
| 
 | |
| static CPUWriteMemoryFunc *pxa2xx_pcmcia_common_writefn[] = {
 | |
|     pxa2xx_pcmcia_common_write,
 | |
|     pxa2xx_pcmcia_common_write,
 | |
|     pxa2xx_pcmcia_common_write,
 | |
| };
 | |
| 
 | |
| static CPUReadMemoryFunc *pxa2xx_pcmcia_attr_readfn[] = {
 | |
|     pxa2xx_pcmcia_attr_read,
 | |
|     pxa2xx_pcmcia_attr_read,
 | |
|     pxa2xx_pcmcia_attr_read,
 | |
| };
 | |
| 
 | |
| static CPUWriteMemoryFunc *pxa2xx_pcmcia_attr_writefn[] = {
 | |
|     pxa2xx_pcmcia_attr_write,
 | |
|     pxa2xx_pcmcia_attr_write,
 | |
|     pxa2xx_pcmcia_attr_write,
 | |
| };
 | |
| 
 | |
| static CPUReadMemoryFunc *pxa2xx_pcmcia_io_readfn[] = {
 | |
|     pxa2xx_pcmcia_io_read,
 | |
|     pxa2xx_pcmcia_io_read,
 | |
|     pxa2xx_pcmcia_io_read,
 | |
| };
 | |
| 
 | |
| static CPUWriteMemoryFunc *pxa2xx_pcmcia_io_writefn[] = {
 | |
|     pxa2xx_pcmcia_io_write,
 | |
|     pxa2xx_pcmcia_io_write,
 | |
|     pxa2xx_pcmcia_io_write,
 | |
| };
 | |
| 
 | |
| static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
|     if (!s->irq)
 | |
|         return;
 | |
| 
 | |
|     qemu_set_irq(s->irq, level);
 | |
| }
 | |
| 
 | |
| PXA2xxPCMCIAState *pxa2xx_pcmcia_init(target_phys_addr_t base)
 | |
| {
 | |
|     int iomemtype;
 | |
|     PXA2xxPCMCIAState *s;
 | |
| 
 | |
|     s = (PXA2xxPCMCIAState *)
 | |
|             qemu_mallocz(sizeof(PXA2xxPCMCIAState));
 | |
| 
 | |
|     /* Socket I/O Memory Space */
 | |
|     iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_io_readfn,
 | |
|                     pxa2xx_pcmcia_io_writefn, s);
 | |
|     cpu_register_physical_memory(base | 0x00000000, 0x04000000, iomemtype);
 | |
| 
 | |
|     /* Then next 64 MB is reserved */
 | |
| 
 | |
|     /* Socket Attribute Memory Space */
 | |
|     iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_attr_readfn,
 | |
|                     pxa2xx_pcmcia_attr_writefn, s);
 | |
|     cpu_register_physical_memory(base | 0x08000000, 0x04000000, iomemtype);
 | |
| 
 | |
|     /* Socket Common Memory Space */
 | |
|     iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_common_readfn,
 | |
|                     pxa2xx_pcmcia_common_writefn, s);
 | |
|     cpu_register_physical_memory(base | 0x0c000000, 0x04000000, iomemtype);
 | |
| 
 | |
|     if (base == 0x30000000)
 | |
|         s->slot.slot_string = "PXA PC Card Socket 1";
 | |
|     else
 | |
|         s->slot.slot_string = "PXA PC Card Socket 0";
 | |
|     s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
 | |
|     pcmcia_socket_register(&s->slot);
 | |
| 
 | |
|     return s;
 | |
| }
 | |
| 
 | |
| /* Insert a new card into a slot */
 | |
| int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
|     if (s->slot.attached)
 | |
|         return -EEXIST;
 | |
| 
 | |
|     if (s->cd_irq) {
 | |
|         qemu_irq_raise(s->cd_irq);
 | |
|     }
 | |
| 
 | |
|     s->card = card;
 | |
| 
 | |
|     s->slot.attached = 1;
 | |
|     s->card->slot = &s->slot;
 | |
|     s->card->attach(s->card->state);
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| /* Eject card from the slot */
 | |
| int pxa2xx_pcmcia_dettach(void *opaque)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
|     if (!s->slot.attached)
 | |
|         return -ENOENT;
 | |
| 
 | |
|     s->card->detach(s->card->state);
 | |
|     s->card->slot = 0;
 | |
|     s->card = 0;
 | |
| 
 | |
|     s->slot.attached = 0;
 | |
| 
 | |
|     if (s->irq)
 | |
|         qemu_irq_lower(s->irq);
 | |
|     if (s->cd_irq)
 | |
|         qemu_irq_lower(s->cd_irq);
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| /* Who to notify on card events */
 | |
| void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
 | |
| {
 | |
|     PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
 | |
|     s->irq = irq;
 | |
|     s->cd_irq = cd_irq;
 | |
| }
 |