From 300491f988f649fced2ffd5c46c1bc911fee0e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 24 Jun 2021 21:22:01 +0200 Subject: hw/pci-host/bonito: Trace PCI config accesses smaller than 32-bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the datasheet section "5.7.5. Accessing PCI configuration space" the address must be 32-bit aligned. Trace eventual accesses not aligned to 32-bit. Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210624202747.1433023-3-f4bug@amsat.org> --- hw/pci-host/bonito.c | 8 ++++++++ hw/pci-host/trace-events | 3 +++ 2 files changed, 11 insertions(+) (limited to 'hw') diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index afb3d1f81d..751fdcec68 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -52,6 +52,7 @@ #include "hw/misc/unimp.h" #include "hw/registerfields.h" #include "qom/object.h" +#include "trace.h" /* #define DEBUG_BONITO */ @@ -185,6 +186,7 @@ FIELD(BONGENCFG, PCIQUEUE, 12, 1) #define BONITO_PCICONF_IDSEL_OFFSET 11 #define BONITO_PCICONF_FUN_MASK 0x700 /* [10:8] */ #define BONITO_PCICONF_FUN_OFFSET 8 +#define BONITO_PCICONF_REG_MASK_DS (~3) /* Per datasheet */ #define BONITO_PCICONF_REG_MASK 0xFC #define BONITO_PCICONF_REG_OFFSET 0 @@ -495,6 +497,9 @@ static void bonito_spciconf_write(void *opaque, hwaddr addr, uint64_t val, if (pciaddr == 0xffffffff) { return; } + if (addr & ~BONITO_PCICONF_REG_MASK_DS) { + trace_bonito_spciconf_small_access(addr, size); + } /* set the pci address in s->config_reg */ phb->config_reg = (pciaddr) | (1u << 31); @@ -521,6 +526,9 @@ static uint64_t bonito_spciconf_read(void *opaque, hwaddr addr, unsigned size) if (pciaddr == 0xffffffff) { return MAKE_64BIT_MASK(0, size * 8); } + if (addr & ~BONITO_PCICONF_REG_MASK_DS) { + trace_bonito_spciconf_small_access(addr, size); + } /* set the pci address in s->config_reg */ phb->config_reg = (pciaddr) | (1u << 31); diff --git a/hw/pci-host/trace-events b/hw/pci-host/trace-events index f4b3a50cb0..630e9fcc5e 100644 --- a/hw/pci-host/trace-events +++ b/hw/pci-host/trace-events @@ -1,5 +1,8 @@ # See docs/devel/tracing.rst for syntax documentation. +# bonito.c +bonito_spciconf_small_access(uint64_t addr, unsigned size) "PCI config address is smaller then 32-bit, addr: 0x%"PRIx64", size: %u" + # grackle.c grackle_set_irq(int irq_num, int level) "set_irq num %d level %d" -- cgit v1.2.3 From 711ef3373135f879459ece3b3c756b615334b404 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Thu, 24 Jun 2021 21:22:19 +0200 Subject: hw/pci-host/bonito: Allow PCI config accesses smaller than 32-bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When running the official PMON firmware for the Fuloong 2E, we see 8-bit and 16-bit accesses to PCI config space: $ qemu-system-mips64el -M fuloong2e -bios pmon_2e.bin \ -trace -trace bonito\* -trace pci_cfg\* pci_cfg_write vt82c686b-pm 05:4 @0x90 <- 0xeee1 bonito_spciconf_small_access PCI config address is smaller then 32-bit, addr: 0x4d2, size: 2 pci_cfg_write vt82c686b-pm 05:4 @0xd2 <- 0x1 pci_cfg_write vt82c686b-pm 05:4 @0x4 <- 0x1 pci_cfg_write vt82c686b-isa 05:0 @0x4 <- 0x7 bonito_spciconf_small_access PCI config address is smaller then 32-bit, addr: 0x81, size: 1 pci_cfg_read vt82c686b-isa 05:0 @0x81 -> 0x0 bonito_spciconf_small_access PCI config address is smaller then 32-bit, addr: 0x81, size: 1 pci_cfg_write vt82c686b-isa 05:0 @0x81 <- 0x80 bonito_spciconf_small_access PCI config address is smaller then 32-bit, addr: 0x83, size: 1 pci_cfg_write vt82c686b-isa 05:0 @0x83 <- 0x89 bonito_spciconf_small_access PCI config address is smaller then 32-bit, addr: 0x85, size: 1 pci_cfg_write vt82c686b-isa 05:0 @0x85 <- 0x3 bonito_spciconf_small_access PCI config address is smaller then 32-bit, addr: 0x5a, size: 1 pci_cfg_write vt82c686b-isa 05:0 @0x5a <- 0x7 bonito_spciconf_small_access PCI config address is smaller then 32-bit, addr: 0x85, size: 1 pci_cfg_write vt82c686b-isa 05:0 @0x85 <- 0x1 Also this is what the Linux kernel does since it supports the Bonito north bridge: https://elixir.bootlin.com/linux/v2.6.15/source/arch/mips/pci/ops-bonito64.c#L85 So it seems safe to assume the datasheet is incomplete or outdated regarding the address constraints. This problem was exposed by commit 911629e6d3773a8adeab48b ("vt82c686: Fix SMBus IO base and configuration registers"). Reported-by: BALATON Zoltan Suggested-by: Jiaxun Yang Signed-off-by: Philippe Mathieu-Daudé Message-Id: <20210624202747.1433023-4-f4bug@amsat.org> Tested-by: BALATON Zoltan --- hw/pci-host/bonito.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 751fdcec68..a57e81e3a9 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -187,7 +187,7 @@ FIELD(BONGENCFG, PCIQUEUE, 12, 1) #define BONITO_PCICONF_FUN_MASK 0x700 /* [10:8] */ #define BONITO_PCICONF_FUN_OFFSET 8 #define BONITO_PCICONF_REG_MASK_DS (~3) /* Per datasheet */ -#define BONITO_PCICONF_REG_MASK 0xFC +#define BONITO_PCICONF_REG_MASK_HW 0xff /* As seen running PMON */ #define BONITO_PCICONF_REG_OFFSET 0 @@ -466,7 +466,7 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr addr) BONITO_PCICONF_IDSEL_OFFSET; devno = ctz32(idsel); funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET; - regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET; + regno = (cfgaddr & BONITO_PCICONF_REG_MASK_HW) >> BONITO_PCICONF_REG_OFFSET; if (idsel == 0) { error_report("error in bonito pci config address 0x" TARGET_FMT_plx -- cgit v1.2.3 From d5bfbaca39e9a700cabf4266247c93edeaf846de Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 17:35:53 +0100 Subject: g364fb: use RAM memory region for framebuffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the migration stream is already broken, we can use this opportunity to change the framebuffer so that it is migrated as a RAM memory region rather than as an array of bytes. In particular this helps the output of the analyze-migration.py tool which no longer contains a huge array representing the framebuffer contents. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210625163554.14879-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/display/g364fb.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'hw') diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index 8f1725432c..87effbf2b0 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -22,6 +22,7 @@ #include "hw/hw.h" #include "hw/irq.h" #include "hw/qdev-properties.h" +#include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/module.h" #include "ui/console.h" @@ -33,7 +34,6 @@ typedef struct G364State { /* hardware */ - uint8_t *vram; uint32_t vram_size; qemu_irq irq; MemoryRegion mem_vram; @@ -125,7 +125,7 @@ static void g364fb_draw_graphic8(G364State *s) xcursor = ycursor = -65; } - vram = s->vram + s->top_of_screen; + vram = memory_region_get_ram_ptr(&s->mem_vram) + s->top_of_screen; /* XXX: out of range in vram? */ data_display = dd = surface_data(surface); snap = memory_region_snapshot_and_clear_dirty(&s->mem_vram, 0, s->vram_size, @@ -274,6 +274,8 @@ static inline void g364fb_invalidate_display(void *opaque) static void g364fb_reset(G364State *s) { + uint8_t *vram = memory_region_get_ram_ptr(&s->mem_vram); + qemu_irq_lower(s->irq); memset(s->color_palette, 0, sizeof(s->color_palette)); @@ -283,7 +285,7 @@ static void g364fb_reset(G364State *s) s->ctla = 0; s->top_of_screen = 0; s->width = s->height = 0; - memset(s->vram, 0, s->vram_size); + memset(vram, 0, s->vram_size); g364fb_invalidate_display(s); } @@ -450,11 +452,10 @@ static int g364fb_post_load(void *opaque, int version_id) static const VMStateDescription vmstate_g364fb = { .name = "g364fb", - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .post_load = g364fb_post_load, .fields = (VMStateField[]) { - VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, vram_size), VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3), VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9), VMSTATE_UINT16_ARRAY(cursor, G364State, 512), @@ -474,15 +475,12 @@ static const GraphicHwOps g364fb_ops = { static void g364fb_init(DeviceState *dev, G364State *s) { - s->vram = g_malloc0(s->vram_size); - s->con = graphic_console_init(dev, 0, &g364fb_ops, s); memory_region_init_io(&s->mem_ctrl, OBJECT(dev), &g364fb_ctrl_ops, s, "ctrl", 0x180000); - memory_region_init_ram_ptr(&s->mem_vram, NULL, "vram", - s->vram_size, s->vram); - vmstate_register_ram(&s->mem_vram, dev); + memory_region_init_ram(&s->mem_vram, NULL, "g364fb.vram", s->vram_size, + &error_fatal); memory_region_set_log(&s->mem_vram, true, DIRTY_MEMORY_VGA); } -- cgit v1.2.3 From 8660df5ea25ea4e6ee94fca43559165fe7610199 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 17:35:54 +0100 Subject: g364fb: add VMStateDescription for G364SysBusState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently when QEMU attempts to migrate the MIPS magnum machine it crashes due to a mistake in the g364fb VMStateDescription configuration which expects a G364SysBusState and not a G364State. Resolve the issue by adding a new VMStateDescription for G364SysBusState and embedding the existing vmstate_g364fb VMStateDescription inside it using VMSTATE_STRUCT. Signed-off-by: Mark Cave-Ayland Fixes: 97a3f6ffbba ("g364fb: convert to qdev") Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210625163554.14879-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/display/g364fb.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index 87effbf2b0..caca86d773 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -517,6 +517,16 @@ static Property g364fb_sysbus_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static const VMStateDescription vmstate_g364fb_sysbus = { + .name = "g364fb-sysbus", + .version_id = 2, + .minimum_version_id = 2, + .fields = (VMStateField[]) { + VMSTATE_STRUCT(g364, G364SysBusState, 2, vmstate_g364fb, G364State), + VMSTATE_END_OF_LIST() + } +}; + static void g364fb_sysbus_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -525,7 +535,7 @@ static void g364fb_sysbus_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); dc->desc = "G364 framebuffer"; dc->reset = g364fb_sysbus_reset; - dc->vmsd = &vmstate_g364fb; + dc->vmsd = &vmstate_g364fb_sysbus; device_class_set_props(dc, g364fb_sysbus_properties); } -- cgit v1.2.3 From 1ca82a8db03ea3c352d581753b22e8dac4ea8047 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 07:53:52 +0100 Subject: dp8393x: checkpatch fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fix a simple comment typo of "constrainst" to "constraints". Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Tested-by: Finn Thain Message-Id: <20210625065401.30170-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/net/dp8393x.c | 231 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 109 deletions(-) (limited to 'hw') diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index 533a8304d0..56af08f0fe 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -29,14 +29,14 @@ #include #include "qom/object.h" -//#define DEBUG_SONIC +/* #define DEBUG_SONIC */ #define SONIC_PROM_SIZE 0x1000 #ifdef DEBUG_SONIC #define DPRINTF(fmt, ...) \ do { printf("sonic: " fmt , ## __VA_ARGS__); } while (0) -static const char* reg_names[] = { +static const char *reg_names[] = { "CR", "DCR", "RCR", "TCR", "IMR", "ISR", "UTDA", "CTDA", "TPS", "TFC", "TSA0", "TSA1", "TFS", "URDA", "CRDA", "CRBA0", "CRBA1", "RBWC0", "RBWC1", "EOBC", "URRA", "RSA", "REA", "RRP", @@ -185,7 +185,8 @@ struct dp8393xState { AddressSpace as; }; -/* Accessor functions for values which are formed by +/* + * Accessor functions for values which are formed by * concatenating two 16 bit device registers. By putting these * in their own functions with a uint32_t return type we avoid the * pitfall of implicit sign extension where ((x << 16) | y) is a @@ -350,8 +351,7 @@ static void dp8393x_do_read_rra(dp8393xState *s) } /* Warn the host if CRBA now has the last available resource */ - if (s->regs[SONIC_RRP] == s->regs[SONIC_RWP]) - { + if (s->regs[SONIC_RRP] == s->regs[SONIC_RWP]) { s->regs[SONIC_ISR] |= SONIC_ISR_RBE; dp8393x_update_irq(s); } @@ -364,7 +364,8 @@ static void dp8393x_do_software_reset(dp8393xState *s) { timer_del(s->watchdog); - s->regs[SONIC_CR] &= ~(SONIC_CR_LCAM | SONIC_CR_RRRA | SONIC_CR_TXP | SONIC_CR_HTX); + s->regs[SONIC_CR] &= ~(SONIC_CR_LCAM | SONIC_CR_RRRA | SONIC_CR_TXP | + SONIC_CR_HTX); s->regs[SONIC_CR] |= SONIC_CR_RST | SONIC_CR_RXDIS; } @@ -490,8 +491,10 @@ static void dp8393x_do_transmit_packets(dp8393xState *s) /* Handle Ethernet checksum */ if (!(s->regs[SONIC_TCR] & SONIC_TCR_CRCI)) { - /* Don't append FCS there, to look like slirp packets - * which don't have one */ + /* + * Don't append FCS there, to look like slirp packets + * which don't have one + */ } else { /* Remove existing FCS */ tx_len -= 4; @@ -558,26 +561,34 @@ static void dp8393x_do_command(dp8393xState *s, uint16_t command) s->regs[SONIC_CR] |= (command & SONIC_CR_MASK); - if (command & SONIC_CR_HTX) + if (command & SONIC_CR_HTX) { dp8393x_do_halt_transmission(s); - if (command & SONIC_CR_TXP) + } + if (command & SONIC_CR_TXP) { dp8393x_do_transmit_packets(s); - if (command & SONIC_CR_RXDIS) + } + if (command & SONIC_CR_RXDIS) { dp8393x_do_receiver_disable(s); - if (command & SONIC_CR_RXEN) + } + if (command & SONIC_CR_RXEN) { dp8393x_do_receiver_enable(s); - if (command & SONIC_CR_STP) + } + if (command & SONIC_CR_STP) { dp8393x_do_stop_timer(s); - if (command & SONIC_CR_ST) + } + if (command & SONIC_CR_ST) { dp8393x_do_start_timer(s); - if (command & SONIC_CR_RST) + } + if (command & SONIC_CR_RST) { dp8393x_do_software_reset(s); + } if (command & SONIC_CR_RRRA) { dp8393x_do_read_rra(s); s->regs[SONIC_CR] &= ~SONIC_CR_RRRA; } - if (command & SONIC_CR_LCAM) + if (command & SONIC_CR_LCAM) { dp8393x_do_load_cam(s); + } } static uint64_t dp8393x_read(void *opaque, hwaddr addr, unsigned int size) @@ -587,24 +598,24 @@ static uint64_t dp8393x_read(void *opaque, hwaddr addr, unsigned int size) uint16_t val = 0; switch (reg) { - /* Update data before reading it */ - case SONIC_WT0: - case SONIC_WT1: - dp8393x_update_wt_regs(s); - val = s->regs[reg]; - break; - /* Accept read to some registers only when in reset mode */ - case SONIC_CAP2: - case SONIC_CAP1: - case SONIC_CAP0: - if (s->regs[SONIC_CR] & SONIC_CR_RST) { - val = s->cam[s->regs[SONIC_CEP] & 0xf][2* (SONIC_CAP0 - reg) + 1] << 8; - val |= s->cam[s->regs[SONIC_CEP] & 0xf][2* (SONIC_CAP0 - reg)]; - } - break; - /* All other registers have no special contrainst */ - default: - val = s->regs[reg]; + /* Update data before reading it */ + case SONIC_WT0: + case SONIC_WT1: + dp8393x_update_wt_regs(s); + val = s->regs[reg]; + break; + /* Accept read to some registers only when in reset mode */ + case SONIC_CAP2: + case SONIC_CAP1: + case SONIC_CAP0: + if (s->regs[SONIC_CR] & SONIC_CR_RST) { + val = s->cam[s->regs[SONIC_CEP] & 0xf][2 * (SONIC_CAP0 - reg) + 1] << 8; + val |= s->cam[s->regs[SONIC_CEP] & 0xf][2 * (SONIC_CAP0 - reg)]; + } + break; + /* All other registers have no special contraints */ + default: + val = s->regs[reg]; } DPRINTF("read 0x%04x from reg %s\n", val, reg_names[reg]); @@ -622,75 +633,75 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data, DPRINTF("write 0x%04x to reg %s\n", (uint16_t)val, reg_names[reg]); switch (reg) { - /* Command register */ - case SONIC_CR: - dp8393x_do_command(s, val); - break; - /* Prevent write to read-only registers */ - case SONIC_CAP2: - case SONIC_CAP1: - case SONIC_CAP0: - case SONIC_SR: - case SONIC_MDT: - DPRINTF("writing to reg %d invalid\n", reg); - break; - /* 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; - } else { - DPRINTF("writing to DCR invalid\n"); - } - break; - case SONIC_DCR2: - if (s->regs[SONIC_CR] & SONIC_CR_RST) { - s->regs[reg] = val & 0xf017; - } else { - DPRINTF("writing to DCR2 invalid\n"); - } - break; - /* 12 lower bytes are Read Only */ - case SONIC_TCR: - s->regs[reg] = val & 0xf000; - break; - /* 9 lower bytes are Read Only */ - case SONIC_RCR: - s->regs[reg] = val & 0xffe0; - break; - /* Ignore most significant bit */ - case SONIC_IMR: - s->regs[reg] = val & 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) { - dp8393x_do_read_rra(s); - } - dp8393x_update_irq(s); - break; - /* The guest is required to store aligned pointers here */ - case SONIC_RSA: - case SONIC_REA: - case SONIC_RRP: - case SONIC_RWP: - if (s->regs[SONIC_DCR] & SONIC_DCR_DW) { - s->regs[reg] = val & 0xfffc; - } else { - s->regs[reg] = val & 0xfffe; - } - break; - /* Invert written value for some registers */ - case SONIC_CRCT: - case SONIC_FAET: - case SONIC_MPT: - s->regs[reg] = val ^ 0xffff; - break; - /* All other registers have no special contrainst */ - default: - s->regs[reg] = val; + /* Command register */ + case SONIC_CR: + dp8393x_do_command(s, val); + break; + /* Prevent write to read-only registers */ + case SONIC_CAP2: + case SONIC_CAP1: + case SONIC_CAP0: + case SONIC_SR: + case SONIC_MDT: + DPRINTF("writing to reg %d invalid\n", reg); + break; + /* 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; + } else { + DPRINTF("writing to DCR invalid\n"); + } + break; + case SONIC_DCR2: + if (s->regs[SONIC_CR] & SONIC_CR_RST) { + s->regs[reg] = val & 0xf017; + } else { + DPRINTF("writing to DCR2 invalid\n"); + } + break; + /* 12 lower bytes are Read Only */ + case SONIC_TCR: + s->regs[reg] = val & 0xf000; + break; + /* 9 lower bytes are Read Only */ + case SONIC_RCR: + s->regs[reg] = val & 0xffe0; + break; + /* Ignore most significant bit */ + case SONIC_IMR: + s->regs[reg] = val & 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) { + dp8393x_do_read_rra(s); + } + dp8393x_update_irq(s); + break; + /* The guest is required to store aligned pointers here */ + case SONIC_RSA: + case SONIC_REA: + case SONIC_RRP: + case SONIC_RWP: + if (s->regs[SONIC_DCR] & SONIC_DCR_DW) { + s->regs[reg] = val & 0xfffc; + } else { + s->regs[reg] = val & 0xfffe; + } + break; + /* Invert written value for some registers */ + case SONIC_CRCT: + case SONIC_FAET: + case SONIC_MPT: + s->regs[reg] = val ^ 0xffff; + break; + /* All other registers have no special contrainst */ + default: + s->regs[reg] = val; } if (reg == SONIC_WT0 || reg == SONIC_WT1) { @@ -747,17 +758,18 @@ static int dp8393x_receive_filter(dp8393xState *s, const uint8_t * buf, } /* Check broadcast */ - if ((s->regs[SONIC_RCR] & SONIC_RCR_BRD) && !memcmp(buf, bcast, sizeof(bcast))) { + if ((s->regs[SONIC_RCR] & SONIC_RCR_BRD) && + !memcmp(buf, bcast, sizeof(bcast))) { return SONIC_RCR_BC; } /* Check CAM */ for (i = 0; i < 16; i++) { if (s->regs[SONIC_CE] & (1 << i)) { - /* Entry enabled */ - if (!memcmp(buf, s->cam[i], sizeof(s->cam[i]))) { - return 0; - } + /* Entry enabled */ + if (!memcmp(buf, s->cam[i], sizeof(s->cam[i]))) { + return 0; + } } } @@ -938,7 +950,8 @@ static void dp8393x_reset(DeviceState *dev) s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux/mips */ s->regs[SONIC_CR] = SONIC_CR_RST | SONIC_CR_STP | SONIC_CR_RXDIS; s->regs[SONIC_DCR] &= ~(SONIC_DCR_EXBUS | SONIC_DCR_LBR); - s->regs[SONIC_RCR] &= ~(SONIC_RCR_LB0 | SONIC_RCR_LB1 | SONIC_RCR_BRD | SONIC_RCR_RNT); + s->regs[SONIC_RCR] &= ~(SONIC_RCR_LB0 | SONIC_RCR_LB1 | SONIC_RCR_BRD | + SONIC_RCR_RNT); s->regs[SONIC_TCR] |= SONIC_TCR_NCRS | SONIC_TCR_PTX; s->regs[SONIC_TCR] &= ~SONIC_TCR_BCM; s->regs[SONIC_IMR] = 0; -- cgit v1.2.3 From c0af04a43667e2e50ed347ca9f707b597c874496 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 07:53:53 +0100 Subject: dp8393x: convert to trace-events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Tested-by: Finn Thain Message-Id: <20210625065401.30170-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/net/dp8393x.c | 55 +++++++++++++++++++---------------------------------- hw/net/trace-events | 17 +++++++++++++++++ 2 files changed, 37 insertions(+), 35 deletions(-) (limited to 'hw') diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index 56af08f0fe..ea5b22f680 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -28,14 +28,10 @@ #include "qemu/timer.h" #include #include "qom/object.h" - -/* #define DEBUG_SONIC */ +#include "trace.h" #define SONIC_PROM_SIZE 0x1000 -#ifdef DEBUG_SONIC -#define DPRINTF(fmt, ...) \ -do { printf("sonic: " fmt , ## __VA_ARGS__); } while (0) static const char *reg_names[] = { "CR", "DCR", "RCR", "TCR", "IMR", "ISR", "UTDA", "CTDA", "TPS", "TFC", "TSA0", "TSA1", "TFS", "URDA", "CRDA", "CRBA0", @@ -45,12 +41,6 @@ static const char *reg_names[] = { "SR", "WT0", "WT1", "RSC", "CRCT", "FAET", "MPT", "MDT", "0x30", "0x31", "0x32", "0x33", "0x34", "0x35", "0x36", "0x37", "0x38", "0x39", "0x3a", "0x3b", "0x3c", "0x3d", "0x3e", "DCR2" }; -#else -#define DPRINTF(fmt, ...) do {} while (0) -#endif - -#define SONIC_ERROR(fmt, ...) \ -do { printf("sonic ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0) #define SONIC_CR 0x00 #define SONIC_DCR 0x01 @@ -161,9 +151,7 @@ struct dp8393xState { bool big_endian; bool last_rba_is_full; qemu_irq irq; -#ifdef DEBUG_SONIC int irq_level; -#endif QEMUTimer *watchdog; int64_t wt_last_update; NICConf conf; @@ -270,16 +258,14 @@ static void dp8393x_update_irq(dp8393xState *s) { int level = (s->regs[SONIC_IMR] & s->regs[SONIC_ISR]) ? 1 : 0; -#ifdef DEBUG_SONIC if (level != s->irq_level) { s->irq_level = level; if (level) { - DPRINTF("raise irq, isr is 0x%04x\n", s->regs[SONIC_ISR]); + trace_dp8393x_raise_irq(s->regs[SONIC_ISR]); } else { - DPRINTF("lower irq\n"); + trace_dp8393x_lower_irq(); } } -#endif qemu_set_irq(s->irq, level); } @@ -302,9 +288,9 @@ static void dp8393x_do_load_cam(dp8393xState *s) s->cam[index][3] = dp8393x_get(s, width, 2) >> 8; s->cam[index][4] = dp8393x_get(s, width, 3) & 0xff; s->cam[index][5] = dp8393x_get(s, width, 3) >> 8; - DPRINTF("load cam[%d] with %02x%02x%02x%02x%02x%02x\n", index, - s->cam[index][0], s->cam[index][1], s->cam[index][2], - s->cam[index][3], s->cam[index][4], s->cam[index][5]); + trace_dp8393x_load_cam(index, s->cam[index][0], s->cam[index][1], + s->cam[index][2], s->cam[index][3], + s->cam[index][4], s->cam[index][5]); /* Move to next entry */ s->regs[SONIC_CDC]--; s->regs[SONIC_CDP] += size; @@ -315,7 +301,7 @@ static void dp8393x_do_load_cam(dp8393xState *s) address_space_read(&s->as, dp8393x_cdp(s), MEMTXATTRS_UNSPECIFIED, s->data, size); s->regs[SONIC_CE] = dp8393x_get(s, width, 0); - DPRINTF("load cam done. cam enable mask 0x%04x\n", s->regs[SONIC_CE]); + trace_dp8393x_load_cam_done(s->regs[SONIC_CE]); /* Done */ s->regs[SONIC_CR] &= ~SONIC_CR_LCAM; @@ -338,9 +324,8 @@ static void dp8393x_do_read_rra(dp8393xState *s) s->regs[SONIC_CRBA1] = dp8393x_get(s, width, 1); s->regs[SONIC_RBWC0] = dp8393x_get(s, width, 2); s->regs[SONIC_RBWC1] = dp8393x_get(s, width, 3); - DPRINTF("CRBA0/1: 0x%04x/0x%04x, RBWC0/1: 0x%04x/0x%04x\n", - s->regs[SONIC_CRBA0], s->regs[SONIC_CRBA1], - s->regs[SONIC_RBWC0], s->regs[SONIC_RBWC1]); + trace_dp8393x_read_rra_regs(s->regs[SONIC_CRBA0], s->regs[SONIC_CRBA1], + s->regs[SONIC_RBWC0], s->regs[SONIC_RBWC1]); /* Go to next entry */ s->regs[SONIC_RRP] += size; @@ -444,7 +429,7 @@ static void dp8393x_do_transmit_packets(dp8393xState *s) /* Read memory */ size = sizeof(uint16_t) * 6 * width; s->regs[SONIC_TTDA] = s->regs[SONIC_CTDA]; - DPRINTF("Transmit packet at %08x\n", dp8393x_ttda(s)); + trace_dp8393x_transmit_packet(dp8393x_ttda(s)); address_space_read(&s->as, dp8393x_ttda(s) + sizeof(uint16_t) * width, MEMTXATTRS_UNSPECIFIED, s->data, size); tx_len = 0; @@ -499,7 +484,7 @@ static void dp8393x_do_transmit_packets(dp8393xState *s) /* Remove existing FCS */ tx_len -= 4; if (tx_len < 0) { - SONIC_ERROR("tx_len is %d\n", tx_len); + trace_dp8393x_transmit_txlen_error(tx_len); break; } } @@ -618,7 +603,7 @@ static uint64_t dp8393x_read(void *opaque, hwaddr addr, unsigned int size) val = s->regs[reg]; } - DPRINTF("read 0x%04x from reg %s\n", val, reg_names[reg]); + trace_dp8393x_read(reg, reg_names[reg], val, size); return s->big_endian ? val << 16 : val; } @@ -630,7 +615,7 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data, int reg = addr >> s->it_shift; uint32_t val = s->big_endian ? data >> 16 : data; - DPRINTF("write 0x%04x to reg %s\n", (uint16_t)val, reg_names[reg]); + trace_dp8393x_write(reg, reg_names[reg], val, size); switch (reg) { /* Command register */ @@ -643,21 +628,21 @@ static void dp8393x_write(void *opaque, hwaddr addr, uint64_t data, case SONIC_CAP0: case SONIC_SR: case SONIC_MDT: - DPRINTF("writing to reg %d invalid\n", reg); + trace_dp8393x_write_invalid(reg); break; /* 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; } else { - DPRINTF("writing to DCR invalid\n"); + trace_dp8393x_write_invalid_dcr("DCR"); } break; case SONIC_DCR2: if (s->regs[SONIC_CR] & SONIC_CR_RST) { s->regs[reg] = val & 0xf017; } else { - DPRINTF("writing to DCR2 invalid\n"); + trace_dp8393x_write_invalid_dcr("DCR2"); } break; /* 12 lower bytes are Read Only */ @@ -803,7 +788,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf, } if (padded_len > dp8393x_rbwc(s) * 2) { - DPRINTF("oversize packet, pkt_size is %d\n", pkt_size); + trace_dp8393x_receive_oversize(pkt_size); s->regs[SONIC_ISR] |= SONIC_ISR_RBAE; dp8393x_update_irq(s); s->regs[SONIC_RCR] |= SONIC_RCR_LPKT; @@ -812,7 +797,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf, packet_type = dp8393x_receive_filter(s, buf, pkt_size); if (packet_type < 0) { - DPRINTF("packet not for netcard\n"); + trace_dp8393x_receive_not_netcard(); return -1; } @@ -850,7 +835,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf, checksum = cpu_to_le32(crc32(0, buf, pkt_size)); /* Put packet into RBA */ - DPRINTF("Receive packet at %08x\n", dp8393x_crba(s)); + trace_dp8393x_receive_packet(dp8393x_crba(s)); address = dp8393x_crba(s); address_space_write(&s->as, address, MEMTXATTRS_UNSPECIFIED, buf, pkt_size); @@ -888,7 +873,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf, } /* Write status to memory */ - DPRINTF("Write status at %08x\n", dp8393x_crda(s)); + trace_dp8393x_receive_write_status(dp8393x_crda(s)); dp8393x_put(s, width, 0, s->regs[SONIC_RCR]); /* status */ dp8393x_put(s, width, 1, rx_len); /* byte count */ dp8393x_put(s, width, 2, s->regs[SONIC_TRBA0]); /* pkt_ptr0 */ diff --git a/hw/net/trace-events b/hw/net/trace-events index c28b91ee1a..643338f610 100644 --- a/hw/net/trace-events +++ b/hw/net/trace-events @@ -436,3 +436,20 @@ npcm7xx_emc_received_packet(uint32_t len) "Received %u byte packet" npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x" npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]" npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x" + +# dp8398x.c +dp8393x_raise_irq(int isr) "raise irq, isr is 0x%04x" +dp8393x_lower_irq(void) "lower irq" +dp8393x_load_cam(int idx, int cam0, int cam1, int cam2, int cam3, int cam4, int cam5) "load cam[%d] with 0x%02x0x%02x0x%02x0x%02x0x%02x0x%02x" +dp8393x_load_cam_done(int cen) "load cam done. cam enable mask 0x%04x" +dp8393x_read_rra_regs(int crba0, int crba1, int rbwc0, int rbwc1) "CRBA0/1: 0x%04x/0x%04x, RBWC0/1: 0x%04x/0x%04x" +dp8393x_transmit_packet(int ttda) "Transmit packet at 0x%"PRIx32 +dp8393x_transmit_txlen_error(int len) "tx_len is %d" +dp8393x_read(int reg, const char *name, int val, int size) "reg=0x%x [%s] val=0x%04x size=%d" +dp8393x_write(int reg, const char *name, int val, int size) "reg=0x%x [%s] val=0x%04x size=%d" +dp8393x_write_invalid(int reg) "writing to reg %d invalid" +dp8393x_write_invalid_dcr(const char *name) "writing to %s invalid" +dp8393x_receive_oversize(int size) "oversize packet, pkt_size is %d" +dp8393x_receive_not_netcard(void) "packet not for netcard" +dp8393x_receive_packet(int crba) "Receive packet at 0x%"PRIx32 +dp8393x_receive_write_status(int crba) "Write status at 0x%"PRIx32 -- cgit v1.2.3 From 5d53baf3f5b3e711fd809d9e0b39b29be994ba9c Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 07:53:54 +0100 Subject: hw/mips/jazz: move PROM and checksum calculation from dp8393x device to board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for each board to have its own separate bit storage format and checksum for storing the MAC address. Signed-off-by: Mark Cave-Ayland Tested-by: Finn Thain Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210625065401.30170-4-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/mips/jazz.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c index 1e1cf8154e..89ca8bb910 100644 --- a/hw/mips/jazz.c +++ b/hw/mips/jazz.c @@ -119,6 +119,8 @@ static const MemoryRegionOps dma_dummy_ops = { #define MAGNUM_BIOS_SIZE \ (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX) +#define SONIC_PROM_SIZE 0x1000 + static void mips_jazz_init(MachineState *machine, enum jazz_model_e jazz_model) { @@ -137,6 +139,7 @@ static void mips_jazz_init(MachineState *machine, MemoryRegion *rtc = g_new(MemoryRegion, 1); MemoryRegion *i8042 = g_new(MemoryRegion, 1); MemoryRegion *dma_dummy = g_new(MemoryRegion, 1); + MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1); NICInfo *nd; DeviceState *dev, *rc4030; SysBusDevice *sysbus; @@ -228,6 +231,10 @@ static void mips_jazz_init(MachineState *machine, NULL, "dummy_dma", 0x1000); memory_region_add_subregion(address_space, 0x8000d000, dma_dummy); + memory_region_init_rom(dp8393x_prom, NULL, "dp8393x-jazz.prom", + SONIC_PROM_SIZE, &error_fatal); + memory_region_add_subregion(address_space, 0x8000b000, dp8393x_prom); + /* ISA bus: IO space at 0x90000000, mem space at 0x91000000 */ memory_region_init(isa_io, NULL, "isa-io", 0x00010000); memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000); @@ -275,6 +282,9 @@ static void mips_jazz_init(MachineState *machine, nd->model = g_strdup("dp83932"); } if (strcmp(nd->model, "dp83932") == 0) { + int checksum, i; + uint8_t *prom; + qemu_check_nic_model(nd, "dp83932"); dev = qdev_new("dp8393x"); @@ -285,8 +295,19 @@ static void mips_jazz_init(MachineState *machine, sysbus = SYS_BUS_DEVICE(dev); sysbus_realize_and_unref(sysbus, &error_fatal); sysbus_mmio_map(sysbus, 0, 0x80001000); - sysbus_mmio_map(sysbus, 1, 0x8000b000); sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(rc4030, 4)); + + /* Add MAC address with valid checksum to PROM */ + prom = memory_region_get_ram_ptr(dp8393x_prom); + checksum = 0; + for (i = 0; i < 6; i++) { + prom[i] = nd->macaddr.a[i]; + checksum += prom[i]; + if (checksum > 0xff) { + checksum = (checksum + 1) & 0xff; + } + } + prom[7] = 0xff - checksum; break; } else if (is_help_option(nd->model)) { error_report("Supported NICs: dp83932"); -- cgit v1.2.3 From 408c57331cddd2b9b8964ce5fdd2c14ccd946868 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 07:53:55 +0100 Subject: hw/m68k/q800: move PROM and checksum calculation from dp8393x device to board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for each board to have its own separate bit storage format and checksum for storing the MAC address. Signed-off-by: Mark Cave-Ayland Tested-by: Finn Thain Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210625065401.30170-5-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/m68k/q800.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 11376daa85..491f283a17 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -70,6 +70,8 @@ #define NUBUS_SUPER_SLOT_BASE 0x60000000 #define NUBUS_SLOT_BASE 0xf0000000 +#define SONIC_PROM_SIZE 0x1000 + /* * the video base, whereas it a Nubus address, * is needed by the kernel to have early display and @@ -211,8 +213,10 @@ static void q800_init(MachineState *machine) int32_t initrd_size; MemoryRegion *rom; MemoryRegion *io; + MemoryRegion *dp8393x_prom = g_new(MemoryRegion, 1); + uint8_t *prom; const int io_slice_nb = (IO_SIZE / IO_SLICE) - 1; - int i; + int i, checksum; ram_addr_t ram_size = machine->ram_size; const char *kernel_filename = machine->kernel_filename; const char *initrd_filename = machine->initrd_filename; @@ -319,9 +323,25 @@ static void q800_init(MachineState *machine) sysbus = SYS_BUS_DEVICE(dev); sysbus_realize_and_unref(sysbus, &error_fatal); sysbus_mmio_map(sysbus, 0, SONIC_BASE); - sysbus_mmio_map(sysbus, 1, SONIC_PROM_BASE); sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, 2)); + memory_region_init_rom(dp8393x_prom, NULL, "dp8393x-q800.prom", + SONIC_PROM_SIZE, &error_fatal); + memory_region_add_subregion(get_system_memory(), SONIC_PROM_BASE, + dp8393x_prom); + + /* Add MAC address with valid checksum to PROM */ + prom = memory_region_get_ram_ptr(dp8393x_prom); + checksum = 0; + for (i = 0; i < 6; i++) { + prom[i] = nd_table[0].macaddr.a[i]; + checksum += prom[i]; + if (checksum > 0xff) { + checksum = (checksum + 1) & 0xff; + } + } + prom[7] = 0xff - checksum; + /* SCC */ dev = qdev_new(TYPE_ESCC); -- cgit v1.2.3 From c3250c8e6b3158f9b55bfc457c4e7a940b59d2b0 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 07:53:56 +0100 Subject: dp8393x: remove onboard PROM containing MAC address and checksum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the datasheet the dp8393x chipset does not contain any NVRAM capable of storing a MAC address or checksum. Now that both the MIPS jazz and m68k q800 boards generate the PROM region and checksum themselves, remove the generated PROM from the dp8393x device itself. Signed-off-by: Mark Cave-Ayland Tested-by: Finn Thain Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210625065401.30170-6-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/net/dp8393x.c | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'hw') diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index ea5b22f680..252c0a2664 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -30,8 +30,6 @@ #include "qom/object.h" #include "trace.h" -#define SONIC_PROM_SIZE 0x1000 - static const char *reg_names[] = { "CR", "DCR", "RCR", "TCR", "IMR", "ISR", "UTDA", "CTDA", "TPS", "TFC", "TSA0", "TSA1", "TFS", "URDA", "CRDA", "CRBA0", @@ -157,7 +155,6 @@ struct dp8393xState { NICConf conf; NICState *nic; MemoryRegion mmio; - MemoryRegion prom; /* Registers */ uint8_t cam[16][6]; @@ -966,16 +963,12 @@ 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; - Error *local_err = NULL; address_space_init(&s->as, s->dma_mr, "dp8393x"); memory_region_init_io(&s->mmio, OBJECT(dev), &dp8393x_ops, s, @@ -986,23 +979,6 @@ static void dp8393x_realize(DeviceState *dev, Error **errp) qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s); - - memory_region_init_rom(&s->prom, OBJECT(dev), "dp8393x-prom", - SONIC_PROM_SIZE, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - 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 const VMStateDescription vmstate_dp8393x = { -- cgit v1.2.3 From 846feac2ae1d1dab08c0048807ce802a256179fd Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 07:53:58 +0100 Subject: hw/m68k/q800: fix PROM checksum and MAC address storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The checksum used by MacOS to validate the PROM content is an exclusive-OR rather than a sum over the corresponding bytes. In addition the MAC address must be stored in bit-reversed format as indicated in comments in Linux's macsonic.c. With the PROM contents fixed MacOS starts to probe the device registers when AppleTalk is enabled in the Control Panel. Signed-off-by: Mark Cave-Ayland Tested-by: Finn Thain Message-Id: <20210625065401.30170-8-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/m68k/q800.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'hw') diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 491f283a17..6817c8b5d1 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -334,11 +334,8 @@ static void q800_init(MachineState *machine) prom = memory_region_get_ram_ptr(dp8393x_prom); checksum = 0; for (i = 0; i < 6; i++) { - prom[i] = nd_table[0].macaddr.a[i]; - checksum += prom[i]; - if (checksum > 0xff) { - checksum = (checksum + 1) & 0xff; - } + prom[i] = bitrev8(nd_table[0].macaddr.a[i]); + checksum ^= prom[i]; } prom[7] = 0xff - checksum; -- cgit v1.2.3 From b1600ff19553c7acfe10b43d4f50331deff876d5 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 25 Jun 2021 07:54:01 +0100 Subject: hw/mips/jazz: specify correct endian for dp8393x device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MIPS magnum machines are available in both big endian (mips64) and little endian (mips64el) configurations. Ensure that the dp893x big_endian property is set accordingly using logic similar to that used for the MIPS malta machines. Signed-off-by: Mark Cave-Ayland Tested-by: Finn Thain Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210625065401.30170-11-mark.cave-ayland@ilande.co.uk> Signed-off-by: Philippe Mathieu-Daudé --- hw/mips/jazz.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c index 89ca8bb910..ee1789183e 100644 --- a/hw/mips/jazz.c +++ b/hw/mips/jazz.c @@ -126,7 +126,7 @@ static void mips_jazz_init(MachineState *machine, { MemoryRegion *address_space = get_system_memory(); char *filename; - int bios_size, n; + int bios_size, n, big_endian; Clock *cpuclk; MIPSCPU *cpu; MIPSCPUClass *mcc; @@ -158,6 +158,12 @@ static void mips_jazz_init(MachineState *machine, [JAZZ_PICA61] = {33333333, 4}, }; +#ifdef TARGET_WORDS_BIGENDIAN + big_endian = 1; +#else + big_endian = 0; +#endif + if (machine->ram_size > 256 * MiB) { error_report("RAM size more than 256Mb is not supported"); exit(EXIT_FAILURE); @@ -290,6 +296,7 @@ static void mips_jazz_init(MachineState *machine, dev = qdev_new("dp8393x"); qdev_set_nic_properties(dev, nd); qdev_prop_set_uint8(dev, "it_shift", 2); + qdev_prop_set_bit(dev, "big_endian", big_endian > 0); object_property_set_link(OBJECT(dev), "dma_mr", OBJECT(rc4030_dma_mr), &error_abort); sysbus = SYS_BUS_DEVICE(dev); -- cgit v1.2.3 From a13bfa5a056b2ffe5f2ce71170c15772fa3b2cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Sun, 1 Dec 2019 21:26:59 +0100 Subject: hw/mips/jazz: Map the UART devices unconditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using the Magnum ARC firmware we can see accesses to the UART1 being rejected, because the device is not mapped: $ qemu-system-mips64el -M magnum -d guest_errors,unimp -bios NTPROM.RAW Invalid access at addr 0x80007004, size 1, region '(null)', reason: rejected Invalid access at addr 0x80007001, size 1, region '(null)', reason: rejected Invalid access at addr 0x80007002, size 1, region '(null)', reason: rejected Invalid access at addr 0x80007003, size 1, region '(null)', reason: rejected Invalid access at addr 0x80007004, size 1, region '(null)', reason: rejected Since both UARTs are present (soldered on the board) regardless of whether there are character devices connected, map them unconditionally. (This code pre-dated commit 12051d82f004 which made it safe to pass NULL in as a chardev to serial devices.) Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Message-Id: <20210629053704.2584504-1-f4bug@amsat.org> --- hw/mips/jazz.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'hw') diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c index ee1789183e..d6183e1882 100644 --- a/hw/mips/jazz.c +++ b/hw/mips/jazz.c @@ -361,16 +361,12 @@ static void mips_jazz_init(MachineState *machine, memory_region_add_subregion(address_space, 0x80005000, i8042); /* Serial ports */ - if (serial_hd(0)) { - serial_mm_init(address_space, 0x80006000, 0, - qdev_get_gpio_in(rc4030, 8), 8000000 / 16, - serial_hd(0), DEVICE_NATIVE_ENDIAN); - } - if (serial_hd(1)) { - serial_mm_init(address_space, 0x80007000, 0, - qdev_get_gpio_in(rc4030, 9), 8000000 / 16, - serial_hd(1), DEVICE_NATIVE_ENDIAN); - } + serial_mm_init(address_space, 0x80006000, 0, + qdev_get_gpio_in(rc4030, 8), 8000000 / 16, + serial_hd(0), DEVICE_NATIVE_ENDIAN); + serial_mm_init(address_space, 0x80007000, 0, + qdev_get_gpio_in(rc4030, 9), 8000000 / 16, + serial_hd(1), DEVICE_NATIVE_ENDIAN); /* Parallel port */ if (parallel_hds[0]) -- cgit v1.2.3