net/dp8393x improvements
cover net/dp8393x improvements
Hi,
This patchset improves dp8393x network card emulation to current QEMU standards, mostly decouples it from MIPS rc4030 chipset emulation, and add PROM and load/save functionalities.
Only required cleanup has been done on the rc4030 side.
Patchset has been tested on MIPS Jazz emulation and on (yet unpublished) m68k Quadra 800 emulation.
I expect those patches go through a MIPS tree, as rc4030 and dp8393x are currently only used in MIPS Jazz emulation.
Hervé Poussineau (8):
rc4030: create custom DMA address space
rc4030: use AddressSpace and address_space_rw in users net/dp8393x: always calculate proper checksums net/dp8393x: do not use old_mmio accesses net/dp8393x: use dp8393x_ prefix for all functions net/dp8393x: QOM'ify
net/dp8393x: add PROM to store MAC address net/dp8393x: add load/save support
hw/dma/rc4030.c | 166 ++++++++++++++++------- hw/mips/mips_jazz.c | 17 ++- hw/net/dp8393x.c | 343 ++++++++++++++++++++++++------------------------ include/hw/mips/mips.h | 13 +- 4 files changed, 305 insertions(+), 234 deletions(-)
Signature · 1 line
1.7.10.4
PATCH 1/8 rc4030: create custom DMA address space
Add a new memory region in system address space where DMA address space definition (the 'translation table') belongs, so we can update on the fly the DMA address space.
--- hw/dma/rc4030.c | 154 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 117 insertions(+), 37 deletions(-)
hw/dma/rc4030.c +117 -37
@@ -25,6 +25,7 @@#include "hw/hw.h" #include "hw/mips/mips.h" #include "qemu/timer.h" +#include "exec/address-spaces.h" /********************************************************/ /* debug rc4030 */
@@ -47,6 +48,8 @@ do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } whi/********************************************************/ /* rc4030 emulation */ +#define MAX_TL_ENTRIES 512 + typedef struct dma_pagetable_entry { int32_t frame; int32_t owner;
@@ -96,6 +99,11 @@ typedef struct rc4030Stateqemu_irq timer_irq;qemu_irq jazz_bus_irq; +MemoryRegion dma_tt;/* translation table */ +MemoryRegion dma_mrs[MAX_TL_ENTRIES ];/* translation aliases */ +MemoryRegion dma_mr;/* whole DMA memory region */ +AddressSpace dma_as; +MemoryRegion iomem_chipset;MemoryRegion iomem_jazzio; } rc4030State;
@@ -265,6 +273,89 @@ static uint32_t rc4030_readb(void *opaque, hwaddr addr)return (v >> (8 * (addr &0x3 ))) &0xff ; } +static void rc4030_dma_as_update_one (rc4030State *s,int index,uint32_t frame) +{ +if (index <MAX_TL_ENTRIES ) { +memory_region_set_enabled (&s->dma_mrs[index], false); + } + +if (!frame) { +return ; + } + +if (index >=MAX_TL_ENTRIES ) { +qemu_log_mask (LOG_UNIMP , +"rc4030: trying to use too high " +"translation table entry %d (max allowed=%d)" , + index,MAX_TL_ENTRIES ); +return ; + } +memory_region_set_alias_offset (&s->dma_mrs[index], frame); +memory_region_set_enabled (&s->dma_mrs[index], true); +} + +static void rc4030_dma_tt_write (void *opaque,hwaddr addr,uint64_t data, +unsigned int size) +{ +rc4030State *s = opaque; + +/* write memory */ +memcpy (memory_region_get_ram_ptr (&s->dma_tt) + addr, &data, size); + +/* update dma address space (only if frame field has been written) */ +if (addr %sizeof (dma_pagetable_entry) ==0 ) { +int index = addr /sizeof (dma_pagetable_entry); +memory_region_transaction_begin (); +rc4030_dma_as_update_one (s, index, (uint32_t )data); +memory_region_transaction_commit (); + } +} + +static const MemoryRegionOps rc4030_dma_tt_ops = { + .write = rc4030_dma_tt_write, + .impl.min_access_size =4 , + .impl.max_access_size =4 , +}; + +static void rc4030_dma_tt_update (rc4030State *s,uint32_t new_tl_base, +uint32_t new_tl_limit) +{ +int entries, i; +dma_pagetable_entry *dma_tl_contents; + +if (s->dma_tl_limit) { +/* write old dma tl table to physical memory */ +memory_region_del_subregion (get_system_memory (), &s->dma_tt); +cpu_physical_memory_write (s->dma_tl_limit &0x7fffffff , +memory_region_get_ram_ptr (&s->dma_tt), + s->dma_tl_limit); + } + + s->dma_tl_base = new_tl_base; + s->dma_tl_limit = new_tl_limit; + new_tl_base &=0x7fffffff ; + +if (s->dma_tl_limit) { +memory_region_init_rom_device (&s->dma_tt,NULL , + &rc4030_dma_tt_ops, s,"dma_tt" , + s->dma_tl_limit,NULL ); + dma_tl_contents =memory_region_get_ram_ptr (&s->dma_tt); +cpu_physical_memory_read (new_tl_base, dma_tl_contents, s->dma_tl_limit); + +memory_region_transaction_begin (); + entries = s->dma_tl_limit /sizeof (dma_pagetable_entry); +for (i =0 ; i < entries; i++) { +rc4030_dma_as_update_one (s, i, dma_tl_contents[i].frame); + } +memory_region_add_subregion (get_system_memory (), new_tl_base, + &s->dma_tt); +memory_region_transaction_commit (); + }else { +memory_region_init (&s->dma_tt,NULL ,"dma_tt" ,0 ); + } +} + +static void rc4030_writel (void *opaque,hwaddr addr,uint32_t val) {rc4030State *s = opaque;
@@ -279,11 +370,11 @@ static void rc4030_writel(void *opaque, hwaddr addr, uint32_t val)break ;/* DMA transl. table base */ case 0x0018 : - s->dma_tl_base = val; +rc4030_dma_tt_update (s, val, s->dma_tl_limit);break ;/* DMA transl. table limit */ case 0x0020 : - s->dma_tl_limit = val; +rc4030_dma_tt_update (s, s->dma_tl_base, val);break ;/* DMA transl. table invalidated */ case 0x0028 :
@@ -590,7 +681,7 @@ static void rc4030_reset(void *opaque) s->invalid_address_register =0 ;memset (s->dma_regs,0 ,sizeof (s->dma_regs)); - s->dma_tl_base = s->dma_tl_limit =0 ; +rc4030_dma_tt_update (s,0 ,0 ); s->remote_failed_address = s->memory_failed_address =0 ; s->cache_maint =0 ;
@@ -675,39 +766,7 @@ static void rc4030_save(QEMUFile *f, void *opaque)void rc4030_dma_memory_rw (void *opaque,hwaddr addr,uint8_t *buf,int len,int is_write) {rc4030State *s = opaque; -hwaddr entry_addr; -hwaddr phys_addr; -dma_pagetable_entry entry; -int index; -int ncpy, i; - - i =0 ; -for (;;) { -if (i == len) { -break ; - } - - ncpy =DMA_PAGESIZE - (addr & (DMA_PAGESIZE -1 )); -if (ncpy > len - i) - ncpy = len - i; - -/* Get DMA translation table entry */ - index = addr /DMA_PAGESIZE ; -if (index >= s->dma_tl_limit /sizeof (dma_pagetable_entry)) { -break ; - } - entry_addr = s->dma_tl_base + index *sizeof (dma_pagetable_entry); -/* XXX: not sure. should we really use only lowest bits? */ - entry_addr &=0x7fffffff ; -cpu_physical_memory_read (entry_addr, &entry,sizeof (entry)); - -/* Read/write data at right place */ - phys_addr = entry.frame + (addr & (DMA_PAGESIZE -1 )); -cpu_physical_memory_rw (phys_addr, &buf[i], ncpy, is_write); - - i += ncpy; - addr += ncpy; - } +address_space_rw (&s->dma_as, addr, buf, len, is_write); }static void rc4030_do_dma (void *opaque,int n,uint8_t *buf,int len,int is_write)
@@ -715,6 +774,7 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_wrirc4030State *s = opaque;hwaddr dma_addr;int dev_to_mem; +int i; s->dma_regs[n][DMA_REG_ENABLE ] &= ~(DMA_FLAG_TC_INTR |DMA_FLAG_MEM_INTR |DMA_FLAG_ADDR_INTR );
@@ -733,7 +793,16 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_wri dma_addr = s->dma_regs[n][DMA_REG_ADDRESS ];/* Read/write data at right place */ -rc4030_dma_memory_rw (opaque, dma_addr, buf, len, is_write); +for (i =0 ; i < len; ) { +int ncpy =DMA_PAGESIZE - (dma_addr & (DMA_PAGESIZE -1 )); +if (ncpy > len - i) { + ncpy = len - i; + } +address_space_rw (&s->dma_as, dma_addr, buf + i, ncpy, is_write); + + dma_addr += ncpy; + i += ncpy; + } s->dma_regs[n][DMA_REG_ENABLE ] |=DMA_FLAG_TC_INTR ; s->dma_regs[n][DMA_REG_COUNT ] -= len;
@@ -800,6 +869,7 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, MemoryRegion *sysmem) {rc4030State *s; +int i; s =g_malloc0 (sizeof (rc4030State));
@@ -821,5 +891,15 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, "rc4030.jazzio", 0x00001000);memory_region_add_subregion (sysmem,0xf0000000 , &s->iomem_jazzio); +memory_region_init (&s->dma_tt,NULL ,"dma_tt" ,0 ); +memory_region_init (&s->dma_mr,NULL ,"dma" ,INT32_MAX ); +for (i =0 ; i <MAX_TL_ENTRIES ; ++i) { +memory_region_init_alias (&s->dma_mrs[i],NULL ,"dma-alias" , +get_system_memory (),0 ,DMA_PAGESIZE ); +memory_region_set_enabled (&s->dma_mrs[i], false); +memory_region_add_subregion (&s->dma_mr, i *DMA_PAGESIZE , + &s->dma_mrs[i]); + } +address_space_init (&s->dma_as, &s->dma_mr,"rc4030_dma" );return s; }
Signature · 1 line
1.7.10.4
Re: [Qemu-devel] [PATCH 1/8] rc4030: create custom DMA address space
Quoted 5 lines · Hervé Poussineau
Add a new memory region in system address space where DMA address space definition (the 'translation table') belongs, so we can update on the fly the DMA address space.
Signed-off-by Hervé Poussineau <[email protected]>
Would it make sense to just use an IOMMU region for the DMA address space?
Paolo
Re: [Qemu-devel] [PATCH 1/8] rc4030: create custom DMA address space
Quoted 10 lines · Paolo Bonzini
Quoted 5 lines · Hervé Poussineau
Add a new memory region in system address space where DMA address space definition (the 'translation table') belongs, so we can update on the fly the DMA address space.
Signed-off-by Hervé Poussineau <[email protected]>Would it make sense to just use an IOMMU region for the DMA address space?
I don't really know. Currently, the first user is the dp8393x network card (a sysbus device), which is connected through the DMA address space. It means that *every* read or write access needs to be translated, even those accessing 1 or 2 bytes. dp8393x has no direct connection to the system memory. On some other machines, like the m68k Quadra 800, the dp8393x is only connected to the system memory.
A second user is the ESP SCSI card in DMA mode, using the DMA address space with the help of the DMA controller.
As DMA address space mapping doesn't change much (except initialization phases), and that it is used for small (1 or 2 bytes) and big transfers (network packets and disk accesses), I thought that an address space was better.
Hervé
Re: [Qemu-devel] [PATCH 1/8] rc4030: create custom DMA address space
Quoted 22 lines · Hervé Poussineau
Quoted 8 lines · Paolo Bonzini
Quoted 5 lines · Hervé Poussineau
Add a new memory region in system address space where DMA address space definition (the 'translation table') belongs, so we can update on the fly
the DMA address space.Quoted 4 lines
Quoted 1 line
Signed-off-by Hervé Poussineau <[email protected]>Would it make sense to just use an IOMMU region for the DMA address space?
I don't really know. Currently, the first user is the dp8393x network card (a sysbus device), which is connected through the DMA address space. It means that *every* read or write access needs to be translated, even those accessing 1 or 2 bytes. dp8393x has no direct connection to the system memory.
On some other machines, like the m68k Quadra 800, the dp8393x is only connected to the system memory.
Quoted 7 lines
A second user is the ESP SCSI card in DMA mode, using the DMA address space with the help of the DMA controller.
As DMA address space mapping doesn't change much (except initialization phases), and that it is used for small (1 or 2 bytes) and big transfers (network packets and disk accesses), I thought that an address space was better.
Both are okay. The IOMMU makes address space changes faster; your scheme is basically a form of caching, it trades update performance for improved translation performance.
The trick you're using with shadowing the RAM is nifty, but it leaks a memory region. I'll reply to the main patch.
Paolo
Re: [Qemu-devel] [PATCH 1/8] rc4030: create custom DMA address space
In reply to Hervé PoussineauQuoted 8 lines · Hervé Poussineau
hw/dma/rc4030.c +8
-0+static const MemoryRegionOps rc4030_dma_tt_ops = { + .impl.min_access_size =4 , + .impl.max_access_size =4 , + .impl.max_access_size =4 , +}; + +static void rc4030_dma_tt_update (rc4030State *s,uint32_t new_tl_base, +uint32_t new_tl_limit)
hw/dma/rc4030.c static uint32_t rc4030_readb(void *opaque, hwaddr addr) · line 331
Quoted 10 lines
hw/dma/rc4030.c +10
-0+{ +int entries, i; +dma_pagetable_entry *dma_tl_contents; + +if (s->dma_tl_limit) { +/* write old dma tl table to physical memory */ +memory_region_del_subregion (get_system_memory (), &s->dma_tt); +cpu_physical_memory_write (s->dma_tl_limit &0x7fffffff , +memory_region_get_ram_ptr (&s->dma_tt), + s->dma_tl_limit);
You would need object_unparent(&s->dma_tt) here.
However, this breaks the rules for memory region lifetime (see docs/memory.txt).
One solution is to warn here for a large dma_tl_limit and always create a 4K ROMD region. Here you can create an alias into the actual dma_tt region and add/remove/unparent that alias. Aliases can be created and unparented at will.
Quoted 8 lines
hw/dma/rc4030.c +3
-1@@ -733,7 +793,16 @@ static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_wri dma_addr = s->dma_regs[n][DMA_REG_ADDRESS ];/* Read/write data at right place */ -rc4030_dma_memory_rw (opaque, dma_addr, buf, len, is_write); +for (i =0 ; i < len; ) { +int ncpy =DMA_PAGESIZE - (dma_addr & (DMA_PAGESIZE -1 )); +if (ncpy > len - i) {
hw/dma/rc4030.c static void rc4030_do_dma(void *opaque, int n, uint8_t *buf, int len, int is_wri · line 808
Quoted 10 lines
hw/dma/rc4030.c +7
-0+ ncpy = len - i; + } +address_space_rw (&s->dma_as, dma_addr, buf + i, ncpy, is_write); + + dma_addr += ncpy; + i += ncpy; + } s->dma_regs[n][DMA_REG_ENABLE ] |=DMA_FLAG_TC_INTR ; s->dma_regs[n][DMA_REG_COUNT ] -= len;
The loop should not be necessary, address_space_rw does the same.
Paolo
Quoted 25 lines
hw/dma/rc4030.c +11
-0@@ -800,6 +869,7 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, MemoryRegion *sysmem) {rc4030State *s; +int i; s =g_malloc0 (sizeof (rc4030State));@@ -821,5 +891,15 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, "rc4030.jazzio", 0x00001000);memory_region_add_subregion (sysmem,0xf0000000 , &s->iomem_jazzio); +memory_region_init (&s->dma_tt,NULL ,"dma_tt" ,0 ); +memory_region_init (&s->dma_mr,NULL ,"dma" ,INT32_MAX ); +for (i =0 ; i <MAX_TL_ENTRIES ; ++i) { +memory_region_init_alias (&s->dma_mrs[i],NULL ,"dma-alias" , +get_system_memory (),0 ,DMA_PAGESIZE ); +memory_region_set_enabled (&s->dma_mrs[i], false); +memory_region_add_subregion (&s->dma_mr, i *DMA_PAGESIZE , + &s->dma_mrs[i]); + } +address_space_init (&s->dma_as, &s->dma_mr,"rc4030_dma" );return s; }
PATCH 2/8 rc4030: use AddressSpace and address_space_rw in users
In reply to Hervé PoussineauNow that rc4030 internally uses an AddressSpace for DMA handling, make its root memory region public. This is especially usefull for dp8393x netcard, which now uses well known QEMU types and methods.
--- hw/dma/rc4030.c | 14 ++++---------- hw/mips/mips_jazz.c | 6 +++--- hw/net/dp8393x.c | 38 ++++++++++++++++++-------------------- include/hw/mips/mips.h | 10 ++++------ 4 files changed, 29 insertions(+), 39 deletions(-)
hw/dma/rc4030.c +4 -10
@@ -763,12 +763,6 @@ static void rc4030_save(QEMUFile *f, void *opaque)qemu_put_be32 (f, s->itr); } -void rc4030_dma_memory_rw (void *opaque,hwaddr addr,uint8_t *buf,int len,int is_write) -{ -rc4030State *s = opaque; -address_space_rw (&s->dma_as, addr, buf, len, is_write); -} -static void rc4030_do_dma (void *opaque,int n,uint8_t *buf,int len,int is_write) {rc4030State *s = opaque;
@@ -864,9 +858,9 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n)return s; } -void *rc4030_init (qemu_irq timer,qemu_irq jazz_bus, -qemu_irq **irqs,rc4030_dma **dmas, -MemoryRegion *sysmem) +MemoryRegion *rc4030_init (qemu_irq timer,qemu_irq jazz_bus, +qemu_irq **irqs,rc4030_dma **dmas, +MemoryRegion *sysmem) {rc4030State *s;int i;
@@ -901,5 +895,5 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, &s->dma_mrs[i]); }address_space_init (&s->dma_as, &s->dma_mr,"rc4030_dma" ); -return s; +return &s->dma_mr; }
hw/mips/mips_jazz.c +3 -3
@@ -135,7 +135,7 @@ static void mips_jazz_init(MachineState *machine,CPUMIPSState *env;qemu_irq *rc4030, *i8259;rc4030_dma *dmas; -void * rc4030_opaque; +MemoryRegion *rc4030_dma_mr;MemoryRegion *isa_mem =g_new (MemoryRegion,1 );MemoryRegion *isa_io =g_new (MemoryRegion,1 );MemoryRegion *rtc =g_new (MemoryRegion,1 );
@@ -217,7 +217,7 @@ static void mips_jazz_init(MachineState *machine,cpu_mips_clock_init (env);/* Chipset */ - rc4030_opaque =rc4030_init (env->irq[6 ], env->irq[3 ], &rc4030, &dmas, + rc4030_dma_mr =rc4030_init (env->irq[6 ], env->irq[3 ], &rc4030, &dmas, address_space);memory_region_init_io (dma_dummy,NULL , &dma_dummy_ops,NULL ,"dummy_dma" ,0x1000 );memory_region_add_subregion (address_space,0x8000d000 , dma_dummy);
@@ -272,7 +272,7 @@ static void mips_jazz_init(MachineState *machine, nd->model =g_strdup ("dp83932" );if (strcmp (nd->model,"dp83932" ) ==0 ) {dp83932_init (nd,0x80001000 ,2 ,get_system_memory (), rc4030[4 ], - rc4030_opaque, rc4030_dma_memory_rw); + rc4030_dma_mr);break ; }else if (is_help_option (nd->model)) {fprintf (stderr,"qemu: Supported NICs: dp83932\n" );
hw/net/dp8393x.c +18 -20
@@ -168,8 +168,7 @@ typedef struct dp8393xState {int loopback_packet;/* Memory access */ -void (*memory_rw)(void *opaque,hwaddr addr,uint8_t *buf,int len,int is_write); -void * mem_opaque; +AddressSpace as; } dp8393xState;static void dp8393x_update_irq (dp8393xState *s)
@@ -201,7 +200,7 @@ static void do_load_cam(dp8393xState *s)while (s->regs[SONIC_CDC ] &0x1f ) {/* Fill current entry */ - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, (s->regs[SONIC_URRA ] <<16 ) | s->regs[SONIC_CDP ], (uint8_t *)data, size,0 ); s->cam[index][0 ] = data[1 * width] &0xff ;
@@ -220,7 +219,7 @@ static void do_load_cam(dp8393xState *s) }/* Read CAM enable */ - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, (s->regs[SONIC_URRA ] <<16 ) | s->regs[SONIC_CDP ], (uint8_t *)data, size,0 ); s->regs[SONIC_CE ] = data[0 * width];
@@ -240,7 +239,7 @@ static void do_read_rra(dp8393xState *s)/* Read memory */ width = (s->regs[SONIC_DCR ] &SONIC_DCR_DW ) ?2 :1 ; size =sizeof (uint16_t ) *4 * width; - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, (s->regs[SONIC_URRA ] <<16 ) | s->regs[SONIC_RRP ], (uint8_t *)data, size,0 );
@@ -353,7 +352,7 @@ static void do_transmit_packets(dp8393xState *s) (s->regs[SONIC_UTDA] << 16) | s->regs[SONIC_CTDA]); size =sizeof (uint16_t ) *6 * width; s->regs[SONIC_TTDA ] = s->regs[SONIC_CTDA ]; - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, ((s->regs[SONIC_UTDA ] <<16 ) | s->regs[SONIC_TTDA ]) +sizeof (uint16_t ) * width, (uint8_t *)data, size,0 ); tx_len =0 ;
@@ -379,7 +378,7 @@ static void do_transmit_packets(dp8393xState *s)if (tx_len + len >sizeof (s->tx_buffer)) { len =sizeof (s->tx_buffer) - tx_len; } - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, (s->regs[SONIC_TSA1 ] <<16 ) | s->regs[SONIC_TSA0 ], &s->tx_buffer[tx_len], len,0 ); tx_len += len;
@@ -388,7 +387,7 @@ static void do_transmit_packets(dp8393xState *s)if (i != s->regs[SONIC_TFC ]) {/* Read next fragment details */ size =sizeof (uint16_t ) *3 * width; - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, ((s->regs[SONIC_UTDA ] <<16 ) | s->regs[SONIC_TTDA ]) +sizeof (uint16_t ) * (4 +3 * i) * width, (uint8_t *)data, size,0 ); s->regs[SONIC_TSA0 ] = data[0 * width];
@@ -422,14 +421,14 @@ static void do_transmit_packets(dp8393xState *s)/* Write status */ data[0 * width] = s->regs[SONIC_TCR ] &0x0fff ;/* status */ size =sizeof (uint16_t ) * width; - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, (s->regs[SONIC_UTDA ] <<16 ) | s->regs[SONIC_TTDA ], (uint8_t *)data, size,1 );if (!(s->regs[SONIC_CR ] &SONIC_CR_HTX )) {/* Read footer of packet */ size =sizeof (uint16_t ) * width; - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, ((s->regs[SONIC_UTDA ] <<16 ) | s->regs[SONIC_TTDA ]) +sizeof (uint16_t ) * (4 +3 * s->regs[SONIC_TFC ]) * width, (uint8_t *)data, size,0 ); s->regs[SONIC_CTDA ] = data[0 * width] & ~0x1 ;
@@ -750,7 +749,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)/* Are we still in resource exhaustion? */ size =sizeof (uint16_t ) *1 * width; address = ((s->regs[SONIC_URDA ] <<16 ) | s->regs[SONIC_CRDA ]) +sizeof (uint16_t ) *5 * width; - s->memory_rw (s->mem_opaque, address, (uint8_t *)data, size,0 ); +address_space_rw (&s->as, address, (uint8_t *)data, size,0 );if (data[0 * width] &0x1 ) {/* Still EOL ; stop reception */ return -1 ;
@@ -773,9 +772,9 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)/* Put packet into RBA */ DPRINTF ("Receive packet at %08x\n" , (s->regs[SONIC_CRBA1 ] <<16 ) | s->regs[SONIC_CRBA0 ]); address = (s->regs[SONIC_CRBA1 ] <<16 ) | s->regs[SONIC_CRBA0 ]; - s->memory_rw (s->mem_opaque, address, (uint8_t *)buf, rx_len,1 ); +address_space_rw (&s->as, address, (uint8_t *)buf, rx_len,1 ); address += rx_len; - s->memory_rw (s->mem_opaque, address, (uint8_t *)&checksum,4 ,1 ); +address_space_rw (&s->as, address, (uint8_t *)&checksum,4 ,1 ); rx_len +=4 ; s->regs[SONIC_CRBA1 ] = address >>16 ; s->regs[SONIC_CRBA0 ] = address &0xffff ;
@@ -803,11 +802,12 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) data[3 * width] = s->regs[SONIC_TRBA1 ];/* pkt_ptr1 */ data[4 * width] = s->regs[SONIC_RSC ];/* seq_no */ size =sizeof (uint16_t ) *5 * width; - s->memory_rw (s->mem_opaque, (s->regs[SONIC_URDA ] <<16 ) | s->regs[SONIC_CRDA ], (uint8_t *)data, size,1 ); +address_space_rw (&s->as, (s->regs[SONIC_URDA ] <<16 ) | s->regs[SONIC_CRDA ], + (uint8_t *)data, size,1 );/* Move to next descriptor */ size =sizeof (uint16_t ) * width; - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, ((s->regs[SONIC_URDA ] <<16 ) | s->regs[SONIC_CRDA ]) +sizeof (uint16_t ) *5 * width, (uint8_t *)data, size,0 ); s->regs[SONIC_LLFA ] = data[0 * width];
@@ -816,7 +816,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) s->regs[SONIC_ISR ] |=SONIC_ISR_RDE ; }else { data[0 * width] =0 ;/* in_use */ - s->memory_rw (s->mem_opaque, +address_space_rw (&s->as, ((s->regs[SONIC_URDA ] <<16 ) | s->regs[SONIC_CRDA ]) +sizeof (uint16_t ) *6 * width, (uint8_t *)data, size,1 ); s->regs[SONIC_CRDA ] = s->regs[SONIC_LLFA ];
@@ -868,8 +868,7 @@ static NetClientInfo net_dp83932_info = {void dp83932_init (NICInfo *nd,hwaddr base,int it_shift,MemoryRegion *address_space, -qemu_irq irq,void * mem_opaque, -void (*memory_rw)(void *opaque,hwaddr addr,uint8_t *buf,int len,int is_write)) +qemu_irq irq,MemoryRegion *dma_mr) {dp8393xState *s;
@@ -878,8 +877,7 @@ void dp83932_init(NICInfo *nd, hwaddr base, int it_shift, s =g_malloc0 (sizeof (dp8393xState)); s->address_space = address_space; - s->mem_opaque = mem_opaque; - s->memory_rw = memory_rw; +address_space_init (&s->as, dma_mr,"dp8393x-dma" ); s->it_shift = it_shift; s->irq = irq; s->watchdog =timer_new_ns (QEMU_CLOCK_VIRTUAL , dp8393x_watchdog, s);
include/hw/mips/mips.h +4 -6
@@ -15,18 +15,16 @@ PCIBus *bonito_init(qemu_irq *pic);/* rc4030.c */ typedef struct rc4030DMAState *rc4030_dma ; -void rc4030_dma_memory_rw (void *opaque,hwaddr addr,uint8_t *buf,int len,int is_write);void rc4030_dma_read (void *dma,uint8_t *buf,int len);void rc4030_dma_write (void *dma,uint8_t *buf,int len); -void *rc4030_init (qemu_irq timer,qemu_irq jazz_bus, -qemu_irq **irqs,rc4030_dma **dmas, -MemoryRegion *sysmem); +MemoryRegion *rc4030_init (qemu_irq timer,qemu_irq jazz_bus, +qemu_irq **irqs,rc4030_dma **dmas, +MemoryRegion *sysmem);/* dp8393x.c */ void dp83932_init (NICInfo *nd,hwaddr base,int it_shift,MemoryRegion *address_space, -qemu_irq irq,void * mem_opaque, -void (*memory_rw)(void *opaque,hwaddr addr,uint8_t *buf,int len,int is_write)); +qemu_irq irq,MemoryRegion *dma_mr);#endif
Signature · 1 line
1.7.10.4
PATCH 3/8 net/dp8393x: always calculate proper checksums
In reply to Hervé Poussineau--- hw/net/dp8393x.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
hw/net/dp8393x.c +1 -11
@@ -21,16 +21,10 @@#include "qemu/timer.h" #include "net/net.h" #include "hw/mips/mips.h" +#include <zlib.h> //#define DEBUG_SONIC -/* Calculate CRCs properly on Rx packets */ -#define SONIC_CALCULATE_RXCRC - -#if defined(SONIC_CALCULATE_RXCRC ) -/* For crc32 */ -#include <zlib.h> -#endif #ifdef DEBUG_SONIC #define DPRINTF (fmt, ...) \
@@ -763,11 +757,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) s->regs[SONIC_TRBA0 ] = s->regs[SONIC_CRBA0 ];/* Calculate the ethernet checksum */ -#ifdef SONIC_CALCULATE_RXCRC checksum =cpu_to_le32 (crc32 (0 , buf, rx_len)); -#else - checksum =0 ; -#endif /* Put packet into RBA */ DPRINTF ("Receive packet at %08x\n" , (s->regs[SONIC_CRBA1 ] <<16 ) | s->regs[SONIC_CRBA0 ]);
Signature · 1 line
1.7.10.4
PATCH 4/8 net/dp8393x: do not use old_mmio accesses
In reply to Hervé Poussineau--- hw/net/dp8393x.c | 112 ++++++++++++++---------------------------------------- 1 file changed, 28 insertions(+), 84 deletions(-)
hw/net/dp8393x.c +28 -84
@@ -473,8 +473,10 @@ static void do_command(dp8393xState *s, uint16_t command)do_load_cam (s); } -static uint16_t read_register (dp8393xState *s,int reg) +static uint64_t dp8393x_read (void *opaque,hwaddr addr,unsigned int size) { +dp8393xState *s = opaque; +int reg = addr >> s->it_shift;uint16_t val =0 ;switch (reg) {
@@ -503,14 +505,18 @@ static uint16_t read_register(dp8393xState *s, int reg)return val; } -static void write_register (dp8393xState *s,int reg,uint16_t val) +static void dp8393x_write (void *opaque,hwaddr addr,uint64_t data, +unsigned int size) { +dp8393xState *s = opaque; +int reg = addr >> s->it_shift; +DPRINTF ("write 0x%04x to reg %s\n" , val, reg_names[reg]);switch (reg) {/* Command register */ case SONIC_CR : -do_command (s, val); +do_command (s, data);break ;/* Prevent write to read-only registers */ case SONIC_CAP2 :
@@ -523,36 +529,36 @@ static void write_register(dp8393xState *s, int reg, uint16_t val)/* Accept write to some registers only when in reset mode */ case SONIC_DCR :if (s->regs[SONIC_CR ] &SONIC_CR_RST ) { - s->regs[reg] = val &0xbfff ; + s->regs[reg] = data &0xbfff ; }else {DPRINTF ("writing to DCR invalid\n" ); }break ;case SONIC_DCR2 :if (s->regs[SONIC_CR ] &SONIC_CR_RST ) { - s->regs[reg] = val &0xf017 ; + s->regs[reg] = data &0xf017 ; }else {DPRINTF ("writing to DCR2 invalid\n" ); }break ;/* 12 lower bytes are Read Only */ case SONIC_TCR : - s->regs[reg] = val &0xf000 ; + s->regs[reg] = data &0xf000 ;break ;/* 9 lower bytes are Read Only */ case SONIC_RCR : - s->regs[reg] = val &0xffe0 ; + s->regs[reg] = data &0xffe0 ;break ;/* Ignore most significant bit */ case SONIC_IMR : - s->regs[reg] = val &0x7fff ; + s->regs[reg] = data &0x7fff ;dp8393x_update_irq (s);break ;/* Clear bits by writing 1 to them */ case SONIC_ISR : - val &= s->regs[reg]; - s->regs[reg] &= ~val; -if (val &SONIC_ISR_RBE ) { + data &= s->regs[reg]; + s->regs[reg] &= ~data; +if (data &SONIC_ISR_RBE ) {do_read_rra (s); }dp8393x_update_irq (s);
@@ -562,17 +568,17 @@ static void write_register(dp8393xState *s, int reg, uint16_t val)case SONIC_REA :case SONIC_RRP :case SONIC_RWP : - s->regs[reg] = val &0xfffe ; + s->regs[reg] = data &0xfffe ;break ;/* Invert written value for some registers */ case SONIC_CRCT :case SONIC_FAET :case SONIC_MPT : - s->regs[reg] = val ^0xffff ; + s->regs[reg] = data ^0xffff ;break ;/* All other registers have no special contrainst */ default : - s->regs[reg] = val; + s->regs[reg] = data; }if (reg ==SONIC_WT0 || reg ==SONIC_WT1 ) {
@@ -580,6 +586,14 @@ static void write_register(dp8393xState *s, int reg, uint16_t val) } } +static const MemoryRegionOps dp8393x_ops = { + .read = dp8393x_read, + .write = dp8393x_write, + .impl.min_access_size =2 , + .impl.max_access_size =2 , + .endianness =DEVICE_NATIVE_ENDIAN , +}; +static void dp8393x_watchdog (void *opaque) {dp8393xState *s = opaque;
@@ -597,76 +611,6 @@ static void dp8393x_watchdog(void *opaque)dp8393x_update_irq (s); } -static uint32_t dp8393x_readw (void *opaque,hwaddr addr) -{ -dp8393xState *s = opaque; -int reg; - -if ((addr & ((1 << s->it_shift) -1 )) !=0 ) { -return 0 ; - } - - reg = addr >> s->it_shift; -return read_register (s, reg); -} - -static uint32_t dp8393x_readb (void *opaque,hwaddr addr) -{ -uint16_t v =dp8393x_readw (opaque, addr & ~0x1 ); -return (v >> (8 * (addr &0x1 ))) &0xff ; -} - -static uint32_t dp8393x_readl (void *opaque,hwaddr addr) -{ -uint32_t v; - v =dp8393x_readw (opaque, addr); - v |=dp8393x_readw (opaque, addr +2 ) <<16 ; -return v; -} - -static void dp8393x_writew (void *opaque,hwaddr addr,uint32_t val) -{ -dp8393xState *s = opaque; -int reg; - -if ((addr & ((1 << s->it_shift) -1 )) !=0 ) { -return ; - } - - reg = addr >> s->it_shift; - -write_register (s, reg, (uint16_t )val); -} - -static void dp8393x_writeb (void *opaque,hwaddr addr,uint32_t val) -{ -uint16_t old_val =dp8393x_readw (opaque, addr & ~0x1 ); - -switch (addr &3 ) { -case 0 : - val = val | (old_val &0xff00 ); -break ; -case 1 : - val = (val <<8 ) | (old_val &0x00ff ); -break ; - } -dp8393x_writew (opaque, addr & ~0x1 , val); -} - -static void dp8393x_writel (void *opaque,hwaddr addr,uint32_t val) -{ -dp8393x_writew (opaque, addr, val &0xffff ); -dp8393x_writew (opaque, addr +2 , (val >>16 ) &0xffff ); -} - -static const MemoryRegionOps dp8393x_ops = { - .old_mmio = { - .read = { dp8393x_readb, dp8393x_readw, dp8393x_readl, }, - .write = { dp8393x_writeb, dp8393x_writew, dp8393x_writel, }, - }, - .endianness =DEVICE_NATIVE_ENDIAN , -}; -static int nic_can_receive (NetClientState *nc) {dp8393xState *s =qemu_get_nic_opaque (nc);
Signature · 1 line
1.7.10.4
PATCH 5/8 net/dp8393x: use dp8393x_ prefix for all functions
In reply to Hervé Poussineau--- hw/net/dp8393x.c | 80 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 39 deletions(-)
hw/net/dp8393x.c +41 -39
@@ -183,7 +183,7 @@ static void dp8393x_update_irq(dp8393xState *s)qemu_set_irq (s->irq, level); } -static void do_load_cam (dp8393xState *s) +static void dp8393x_do_load_cam (dp8393xState *s) {uint16_t data[8 ];int width, size;
@@ -225,7 +225,7 @@ static void do_load_cam(dp8393xState *s)dp8393x_update_irq (s); } -static void do_read_rra (dp8393xState *s) +static void dp8393x_do_read_rra (dp8393xState *s) {uint16_t data[8 ];int width, size;
@@ -265,7 +265,7 @@ static void do_read_rra(dp8393xState *s) s->regs[SONIC_CR ] &= ~SONIC_CR_RRRA ; } -static void do_software_reset (dp8393xState *s) +static void dp8393x_do_software_reset (dp8393xState *s) {timer_del (s->watchdog);
@@ -273,7 +273,7 @@ static void do_software_reset(dp8393xState *s) s->regs[SONIC_CR ] |=SONIC_CR_RST |SONIC_CR_RXDIS ; } -static void set_next_tick (dp8393xState *s) +static void dp8393x_set_next_tick (dp8393xState *s) {uint32_t ticks;int64_t delay;
@@ -289,7 +289,7 @@ static void set_next_tick(dp8393xState *s)timer_mod (s->watchdog, s->wt_last_update + delay); } -static void update_wt_regs (dp8393xState *s) +static void dp8393x_update_wt_regs (dp8393xState *s) {int64_t elapsed;uint32_t val;
@@ -304,33 +304,33 @@ static void update_wt_regs(dp8393xState *s) val -= elapsed /5000000 ; s->regs[SONIC_WT1 ] = (val >>16 ) &0xffff ; s->regs[SONIC_WT0 ] = (val >>0 ) &0xffff ; -set_next_tick (s); +dp8393x_set_next_tick (s); } -static void do_start_timer (dp8393xState *s) +static void dp8393x_do_start_timer (dp8393xState *s) { s->regs[SONIC_CR ] &= ~SONIC_CR_STP ; -set_next_tick (s); +dp8393x_set_next_tick (s); } -static void do_stop_timer (dp8393xState *s) +static void dp8393x_do_stop_timer (dp8393xState *s) { s->regs[SONIC_CR ] &= ~SONIC_CR_ST ; -update_wt_regs (s); +dp8393x_update_wt_regs (s); } -static void do_receiver_enable (dp8393xState *s) +static void dp8393x_do_receiver_enable (dp8393xState *s) { s->regs[SONIC_CR ] &= ~SONIC_CR_RXDIS ; } -static void do_receiver_disable (dp8393xState *s) +static void dp8393x_do_receiver_disable (dp8393xState *s) { s->regs[SONIC_CR ] &= ~SONIC_CR_RXEN ; } -static void do_transmit_packets (dp8393xState *s) +static void dp8393x_do_transmit_packets (dp8393xState *s) {NetClientState *nc =qemu_get_queue (s->nic);uint16_t data[12 ];
@@ -439,12 +439,12 @@ static void do_transmit_packets(dp8393xState *s)dp8393x_update_irq (s); } -static void do_halt_transmission (dp8393xState *s) +static void dp8393x_do_halt_transmission (dp8393xState *s) {/* Nothing to do */ } -static void do_command (dp8393xState *s,uint16_t command) +static void dp8393x_do_command (dp8393xState *s,uint16_t command) {if ((s->regs[SONIC_CR ] &SONIC_CR_RST ) && !(command &SONIC_CR_RST )) { s->regs[SONIC_CR ] &= ~SONIC_CR_RST ;
@@ -454,23 +454,23 @@ static void do_command(dp8393xState *s, uint16_t command) s->regs[SONIC_CR ] |= (command &SONIC_CR_MASK );if (command &SONIC_CR_HTX ) -do_halt_transmission (s); +dp8393x_do_halt_transmission (s);if (command &SONIC_CR_TXP ) -do_transmit_packets (s); +dp8393x_do_transmit_packets (s);if (command &SONIC_CR_RXDIS ) -do_receiver_disable (s); +dp8393x_do_receiver_disable (s);if (command &SONIC_CR_RXEN ) -do_receiver_enable (s); +dp8393x_do_receiver_enable (s);if (command &SONIC_CR_STP ) -do_stop_timer (s); +dp8393x_do_stop_timer (s);if (command &SONIC_CR_ST ) -do_start_timer (s); +dp8393x_do_start_timer (s);if (command &SONIC_CR_RST ) -do_software_reset (s); +dp8393x_do_software_reset (s);if (command &SONIC_CR_RRRA ) -do_read_rra (s); +dp8393x_do_read_rra (s);if (command &SONIC_CR_LCAM ) -do_load_cam (s); +dp8393x_do_load_cam (s); }static uint64_t dp8393x_read (void *opaque,hwaddr addr,unsigned int size)
@@ -483,7 +483,7 @@ static uint64_t dp8393x_read(void *opaque, hwaddr addr, unsigned int size)/* Update data before reading it */ case SONIC_WT0 :case SONIC_WT1 : -update_wt_regs (s); +dp8393x_update_wt_regs (s); val = s->regs[reg];break ;/* Accept read to some registers only when in reset mode */
@@ -516,7 +516,7 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data,switch (reg) {/* Command register */ case SONIC_CR : -do_command (s, data); +dp8393x_do_command (s, data);break ;/* Prevent write to read-only registers */ case SONIC_CAP2 :
@@ -559,7 +559,7 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data, data &= s->regs[reg]; s->regs[reg] &= ~data;if (data &SONIC_ISR_RBE ) { -do_read_rra (s); +dp8393x_do_read_rra (s); }dp8393x_update_irq (s);break ;
@@ -582,7 +582,7 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data, }if (reg ==SONIC_WT0 || reg ==SONIC_WT1 ) { -set_next_tick (s); +dp8393x_set_next_tick (s); } }
@@ -604,14 +604,14 @@ static void dp8393x_watchdog(void *opaque) s->regs[SONIC_WT1 ] =0xffff ; s->regs[SONIC_WT0 ] =0xffff ; -set_next_tick (s); +dp8393x_set_next_tick (s);/* Signal underflow */ s->regs[SONIC_ISR ] |=SONIC_ISR_TC ;dp8393x_update_irq (s); } -static int nic_can_receive (NetClientState *nc) +static int dp8393x_can_receive (NetClientState *nc) {dp8393xState *s =qemu_get_nic_opaque (nc);
@@ -622,7 +622,8 @@ static int nic_can_receive(NetClientState *nc)return 1 ; } -static int receive_filter (dp8393xState *s,const uint8_t * buf,int size) +static int dp8393x_receive_filter (dp8393xState *s,const uint8_t * buf, +int size) {static const uint8_t bcast[] = {0xff ,0xff ,0xff ,0xff ,0xff ,0xff };int i;
@@ -660,7 +661,8 @@ static int receive_filter(dp8393xState *s, const uint8_t * buf, int size)return -1 ; } -static ssize_t nic_receive (NetClientState *nc,const uint8_t * buf,size_t size) +static ssize_t dp8393x_receive (NetClientState *nc,const uint8_t * buf, +size_t size) {dp8393xState *s =qemu_get_nic_opaque (nc);uint16_t data[10 ];
@@ -674,7 +676,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size) s->regs[SONIC_RCR ] &= ~(SONIC_RCR_PRX |SONIC_RCR_LBK |SONIC_RCR_FAER |SONIC_RCR_CRCR |SONIC_RCR_LPKT |SONIC_RCR_BC |SONIC_RCR_MC ); - packet_type =receive_filter (s, buf, size); + packet_type =dp8393x_receive_filter (s, buf, size);if (packet_type <0 ) {DPRINTF ("packet not for netcard\n" );return -1 ;
@@ -759,7 +761,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)if (s->regs[SONIC_RCR ] &SONIC_RCR_LPKT ) {/* Read next RRA */ -do_read_rra (s); +dp8393x_do_read_rra (s); } }
@@ -769,7 +771,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)return size; } -static void nic_reset (void *opaque) +static void dp8393x_reset (void *opaque) {dp8393xState *s = opaque;timer_del (s->watchdog);
@@ -796,8 +798,8 @@ static void nic_reset(void *opaque)static NetClientInfo net_dp83932_info = { .type =NET_CLIENT_OPTIONS_KIND_NIC , .size =sizeof (NICState), - .can_receive = nic_can_receive, - .receive = nic_receive, + .can_receive = dp8393x_can_receive, + .receive = dp8393x_receive, }; void dp83932_init(NICInfo *nd, hwaddr base, int it_shift,
@@ -823,8 +825,8 @@ void dp83932_init(NICInfo *nd, hwaddr base, int it_shift, s->nic =qemu_new_nic (&net_dp83932_info, &s->conf, nd->model, nd->name, s);qemu_format_nic_info_str (qemu_get_queue (s->nic), s->conf.macaddr.a); -qemu_register_reset (nic_reset, s); -nic_reset (s); +qemu_register_reset (dp8393x_reset, s); +dp8393x_reset (s);memory_region_init_io (&s->mmio,NULL , &dp8393x_ops, s,"dp8393x" ,0x40 << it_shift);
Signature · 1 line
1.7.10.4
PATCH 6/8 net/dp8393x: QOM'ify
In reply to Hervé Poussineau--- hw/mips/mips_jazz.c | 12 +++++-- hw/net/dp8393x.c | 83 +++++++++++++++++++++++++++++++++--------------- include/hw/mips/mips.h | 5 --- 3 files changed, 67 insertions(+), 33 deletions(-)
hw/mips/mips_jazz.c +10 -2
@@ -271,8 +271,16 @@ static void mips_jazz_init(MachineState *machine,if (!nd->model) nd->model =g_strdup ("dp83932" );if (strcmp (nd->model,"dp83932" ) ==0 ) { -dp83932_init (nd,0x80001000 ,2 ,get_system_memory (), rc4030[4 ], - rc4030_dma_mr); +qemu_check_nic_model (nd,"dp83932" ); + + dev =qdev_create (NULL ,"dp8393x" ); +qdev_set_nic_properties (dev, nd); +qdev_prop_set_uint8 (dev,"it_shift" ,2 ); +qdev_prop_set_ptr (dev,"dma_mr" , rc4030_dma_mr); +qdev_init_nofail (dev); + sysbus =SYS_BUS_DEVICE (dev); +sysbus_mmio_map (sysbus,0 ,0x80001000 ); +sysbus_connect_irq (sysbus,0 , rc4030[4 ]);break ; }else if (is_help_option (nd->model)) {fprintf (stderr,"qemu: Supported NICs: dp83932\n" );
hw/net/dp8393x.c +57 -26
131 lines not on this page · raw message
include/hw/mips/mips.h +0 -5
@@ -22,9 +22,4 @@ MemoryRegion *rc4030_init(qemu_irq timer, qemu_irq jazz_bus, qemu_irq **irqs, rc4030_dma **dmas, MemoryRegion *sysmem); -/* dp8393x.c */ -void dp83932_init (NICInfo *nd,hwaddr base,int it_shift, -MemoryRegion *address_space, -qemu_irq irq,MemoryRegion *dma_mr); -#endif
Signature · 1 line
1.7.10.4
PATCH 7/8 net/dp8393x: add PROM to store MAC address
In reply to Hervé Poussineau--- hw/mips/mips_jazz.c | 1 + hw/net/dp8393x.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+)
hw/mips/mips_jazz.c +1 -0
@@ -280,6 +280,7 @@ static void mips_jazz_init(MachineState *machine,qdev_init_nofail (dev); sysbus =SYS_BUS_DEVICE (dev);sysbus_mmio_map (sysbus,0 ,0x80001000 ); +sysbus_mmio_map (sysbus,1 ,0x8000b000 );sysbus_connect_irq (sysbus,0 , rc4030[4 ]);break ; }else if (is_help_option (nd->model)) {
hw/net/dp8393x.c +18 -0
@@ -25,6 +25,7 @@//#define DEBUG_SONIC +#define SONIC_PROM_SIZE 0x1000#ifdef DEBUG_SONIC #define DPRINTF (fmt, ...) \
@@ -156,6 +157,7 @@ typedef struct dp8393xState {NICConf conf;NICState *nic;MemoryRegion mmio; +MemoryRegion prom;/* Registers */ uint8_t cam[16 ][6 ];
@@ -813,12 +815,15 @@ static void dp8393x_instance_init(Object *obj)dp8393xState *s =DP8393X (obj);sysbus_init_mmio (sbd, &s->mmio); +sysbus_init_mmio (sbd, &s->prom);sysbus_init_irq (sbd, &s->irq); }static void dp8393x_realize (DeviceState *dev,Error **errp) {dp8393xState *s =DP8393X (dev); +int i, checksum; +uint8_t *prom;address_space_init (&s->as, s->dma_mr,"dp8393x" ); memory_region_init_io(&s->mmio, NULL, &dp8393x_ops, s,
@@ -830,6 +835,19 @@ static void dp8393x_realize(DeviceState *dev, Error **errp) s->watchdog =timer_new_ns (QEMU_CLOCK_VIRTUAL , dp8393x_watchdog, s); s->regs[SONIC_SR ] =0x0004 ;/* only revision recognized by Linux */ + +memory_region_init_rom_device (&s->prom,NULL ,NULL ,NULL , +"dp8393x-prom" ,SONIC_PROM_SIZE ,NULL ); + prom =memory_region_get_ram_ptr (&s->prom); + checksum =0 ; +for (i =0 ; i <6 ; i++) { + prom[i] = s->conf.macaddr.a[i]; + checksum += prom[i]; +if (checksum >0xff ) { + checksum = (checksum +1 ) &0xff ; + } + } + prom[7 ] =0xff - checksum; }static Property dp8393x_properties[] = {
Signature · 1 line
1.7.10.4
PATCH 8/8 net/dp8393x: add load/save support
In reply to Hervé Poussineau--- hw/net/dp8393x.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
hw/net/dp8393x.c +12 -0
@@ -850,6 +850,17 @@ static void dp8393x_realize(DeviceState *dev, Error **errp) prom[7 ] =0xff - checksum; } +static const VMStateDescription vmstate_dp8393x = { + .name ="dp8393x" , + .version_id =0 , + .minimum_version_id =0 , + .fields = (VMStateField []) { +VMSTATE_BUFFER_UNSAFE (cam, dp8393xState,0 ,16 *6 ), +VMSTATE_UINT16_ARRAY (regs, dp8393xState,0x40 ), +VMSTATE_END_OF_LIST () + } +}; +static Property dp8393x_properties[] = {DEFINE_NIC_PROPERTIES (dp8393xState, conf),DEFINE_PROP_PTR ("dma_mr" , dp8393xState, dma_mr),
@@ -864,6 +875,7 @@ static void dp8393x_class_init(ObjectClass *klass, void *data)set_bit (DEVICE_CATEGORY_NETWORK , dc->categories); dc->realize = dp8393x_realize; dc->reset = dp8393x_reset; + dc->vmsd = &vmstate_dp8393x; dc->props = dp8393x_properties; }
Signature · 1 line
1.7.10.4
Leon Alrae
AppliedQuoted 23 lines · Hervé Poussineau
Hi,
This patchset improves dp8393x network card emulation to current QEMU standards, mostly decouples it from MIPS rc4030 chipset emulation, and add PROM and load/save functionalities.
Only required cleanup has been done on the rc4030 side.Patchset has been tested on MIPS Jazz emulation and on (yet unpublished) m68k Quadra 800 emulation.
I expect those patches go through a MIPS tree, as rc4030 and dp8393x are currently only used in MIPS Jazz emulation.
Hervé Poussineau (8):
rc4030: create custom DMA address space
rc4030: use AddressSpace andaddress_space_rwin users net/dp8393x: always calculate proper checksums net/dp8393x: do not useold_mmioaccesses net/dp8393x: usedp8393x_prefix for all functions net/dp8393x: QOM'ify
net/dp8393x: add PROM to store MAC address net/dp8393x: add load/save support
Quoted 6 lines
hw/dma/rc4030.c | 166 ++++++++++++++++------- hw/mips/mips_jazz.c | 17 ++- hw/net/dp8393x.c | 343 ++++++++++++++++++++++++------------------------ include/hw/mips/mips.h | 13 +- 4 files changed, 305 insertions(+), 234 deletions(-)
Applied to mips-next for 2.4, thanks.
In future please remember to Cc Andreas on QOM'ify patches.
Thanks,
Leon
Hi Hervé,
Quoted 24 lines · Leon Alrae
Quoted 23 lines · Hervé Poussineau
Hi,
This patchset improves dp8393x network card emulation to current QEMU standards, mostly decouples it from MIPS rc4030 chipset emulation, and add PROM and load/save functionalities.
Only required cleanup has been done on the rc4030 side.Patchset has been tested on MIPS Jazz emulation and on (yet unpublished) m68k Quadra 800 emulation.
I expect those patches go through a MIPS tree, as rc4030 and dp8393x are currently only used in MIPS Jazz emulation.
Hervé Poussineau (8):
rc4030: create custom DMA address space
rc4030: use AddressSpace andaddress_space_rwin users net/dp8393x: always calculate proper checksums net/dp8393x: do not useold_mmioaccesses net/dp8393x: usedp8393x_prefix for all functions net/dp8393x: QOM'ify
net/dp8393x: add PROM to store MAC address net/dp8393x: add load/save support
Quoted 8 lines
Quoted 6 lines
hw/dma/rc4030.c | 166 ++++++++++++++++------- hw/mips/mips_jazz.c | 17 ++- hw/net/dp8393x.c | 343 ++++++++++++++++++++++++------------------------ include/hw/mips/mips.h | 13 +- 4 files changed, 305 insertions(+), 234 deletions(-)Applied to mips-next for 2.4, thanks.
Since I haven't sent out these patches yet and there were some review comments from Paolo in the meantime
(https://lists.gnu.org/archive/html/qemu-devel/2015-03/msg05491.html),
could you make the required corrections, please?
Thanks,
Leon
Hi Leon,
Quoted 34 lines · Leon Alrae
Hi Hervé,
Quoted 31 lines · Leon Alrae
Quoted 29 lines · Hervé Poussineau
Hi,
This patchset improves dp8393x network card emulation to current QEMU standards, mostly decouples it from MIPS rc4030 chipset emulation, and add PROM and load/save functionalities.
Only required cleanup has been done on the rc4030 side.Patchset has been tested on MIPS Jazz emulation and on (yet unpublished) m68k Quadra 800 emulation.
I expect those patches go through a MIPS tree, as rc4030 and dp8393x are currently only used in MIPS Jazz emulation.
Hervé Poussineau (8):
rc4030: create custom DMA address space
rc4030: use AddressSpace andaddress_space_rwin users net/dp8393x: always calculate proper checksums net/dp8393x: do not useold_mmioaccesses net/dp8393x: usedp8393x_prefix for all functions net/dp8393x: QOM'ify
net/dp8393x: add PROM to store MAC address net/dp8393x: add load/save supporthw/dma/rc4030.c | 166 ++++++++++++++++------- hw/mips/mips_jazz.c | 17 ++- hw/net/dp8393x.c | 343 ++++++++++++++++++++++++------------------------ include/hw/mips/mips.h | 13 +- 4 files changed, 305 insertions(+), 234 deletions(-)
Quoted 6 lines
Quoted 1 line
Applied to mips-next for 2.4, thanks.
Since I haven't sent out these patches yet and there were some review comments from Paolo in the meantime
(https://lists.gnu.org/archive/html/qemu-devel/2015-03/msg05491.html),
could you make the required corrections, please?
I'll do the required corrections, and send a new patch series later (with some bonuses). You can remove these patches from mips-next currently.
Regards,
Hervé