From e0db904d1dc97be0eed7fbb52954d03ec05bee07 Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Sun, 2 Feb 2014 02:44:41 +0400 Subject: hw/xtensa: add support for ML605 and KC705 FPGA board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Max Filippov Reviewed-by: Andreas Färber --- hw/xtensa/xtensa_lx60.c | 51 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c index 22e124d..49c58d1 100644 --- a/hw/xtensa/xtensa_lx60.c +++ b/hw/xtensa/xtensa_lx60.c @@ -40,6 +40,7 @@ #include "xtensa_bootparam.h" typedef struct LxBoardDesc { + hwaddr flash_base; size_t flash_size; size_t flash_sector_size; size_t sram_size; @@ -219,7 +220,7 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args) dinfo = drive_get(IF_PFLASH, 0, 0); if (dinfo) { - flash = pflash_cfi01_register(0xf8000000, + flash = pflash_cfi01_register(board->flash_base, NULL, "lx60.io.flash", board->flash_size, dinfo->bdrv, board->flash_sector_size, board->flash_size / board->flash_sector_size, @@ -265,7 +266,9 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args) MemoryRegion *flash_io = g_malloc(sizeof(*flash_io)); memory_region_init_alias(flash_io, NULL, "lx60.flash", - flash_mr, 0, board->flash_size); + flash_mr, 0, + board->flash_size < 0x02000000 ? + board->flash_size : 0x02000000); memory_region_add_subregion(system_memory, 0xfe000000, flash_io); } @@ -275,7 +278,8 @@ static void lx_init(const LxBoardDesc *board, QEMUMachineInitArgs *args) static void xtensa_lx60_init(QEMUMachineInitArgs *args) { static const LxBoardDesc lx60_board = { - .flash_size = 0x400000, + .flash_base = 0xf8000000, + .flash_size = 0x00400000, .flash_sector_size = 0x10000, .sram_size = 0x20000, }; @@ -285,13 +289,36 @@ static void xtensa_lx60_init(QEMUMachineInitArgs *args) static void xtensa_lx200_init(QEMUMachineInitArgs *args) { static const LxBoardDesc lx200_board = { - .flash_size = 0x1000000, + .flash_base = 0xf8000000, + .flash_size = 0x01000000, .flash_sector_size = 0x20000, .sram_size = 0x2000000, }; lx_init(&lx200_board, args); } +static void xtensa_ml605_init(QEMUMachineInitArgs *args) +{ + static const LxBoardDesc ml605_board = { + .flash_base = 0xf8000000, + .flash_size = 0x02000000, + .flash_sector_size = 0x20000, + .sram_size = 0x2000000, + }; + lx_init(&ml605_board, args); +} + +static void xtensa_kc705_init(QEMUMachineInitArgs *args) +{ + static const LxBoardDesc kc705_board = { + .flash_base = 0xf0000000, + .flash_size = 0x08000000, + .flash_sector_size = 0x20000, + .sram_size = 0x2000000, + }; + lx_init(&kc705_board, args); +} + static QEMUMachine xtensa_lx60_machine = { .name = "lx60", .desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")", @@ -306,10 +333,26 @@ static QEMUMachine xtensa_lx200_machine = { .max_cpus = 4, }; +static QEMUMachine xtensa_ml605_machine = { + .name = "ml605", + .desc = "ml605 EVB (" XTENSA_DEFAULT_CPU_MODEL ")", + .init = xtensa_ml605_init, + .max_cpus = 4, +}; + +static QEMUMachine xtensa_kc705_machine = { + .name = "kc705", + .desc = "kc705 EVB (" XTENSA_DEFAULT_CPU_MODEL ")", + .init = xtensa_kc705_init, + .max_cpus = 4, +}; + static void xtensa_lx_machines_init(void) { qemu_register_machine(&xtensa_lx60_machine); qemu_register_machine(&xtensa_lx200_machine); + qemu_register_machine(&xtensa_ml605_machine); + qemu_register_machine(&xtensa_kc705_machine); } machine_init(xtensa_lx_machines_init); -- cgit v1.1 From b807b5ff894b79e31ccd2ff5bd023577ecf45a6a Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Mon, 3 Feb 2014 07:57:55 +0400 Subject: opencores_eth: flush queue whenever can_receive can go from false to true The following registers control whether MAC can receive frames: - MODER.RXEN bit that enables/disables receiver; - TX_BD_NUM register that specifies number of RX descriptors. Notify QEMU networking core when the MAC is ready to receive frames. Discard frame and raise BUSY interrupt when the frame arrives but the current RX descriptor is not empty. Signed-off-by: Max Filippov Reviewed-by: Paolo Bonzini --- hw/net/opencores_eth.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c index 4118d54..4a44304 100644 --- a/hw/net/opencores_eth.c +++ b/hw/net/opencores_eth.c @@ -169,6 +169,7 @@ enum { }; enum { + INT_SOURCE_BUSY = 0x10, INT_SOURCE_RXB = 0x4, INT_SOURCE_TXB = 0x1, }; @@ -351,8 +352,7 @@ static int open_eth_can_receive(NetClientState *nc) OpenEthState *s = qemu_get_nic_opaque(nc); return GET_REGBIT(s, MODER, RXEN) && - (s->regs[TX_BD_NUM] < 0x80) && - (rx_desc(s)->len_flags & RXD_E); + (s->regs[TX_BD_NUM] < 0x80); } static ssize_t open_eth_receive(NetClientState *nc, @@ -402,6 +402,12 @@ static ssize_t open_eth_receive(NetClientState *nc, desc *desc = rx_desc(s); size_t copy_size = GET_REGBIT(s, MODER, HUGEN) ? 65536 : maxfl; + if (!(desc->len_flags & RXD_E)) { + open_eth_int_source_write(s, + s->regs[INT_SOURCE] | INT_SOURCE_BUSY); + return size; + } + desc->len_flags &= ~(RXD_CF | RXD_M | RXD_OR | RXD_IS | RXD_DN | RXD_TL | RXD_SF | RXD_CRC | RXD_LC); @@ -551,6 +557,15 @@ static uint64_t open_eth_reg_read(void *opaque, return v; } +static void open_eth_notify_can_receive(OpenEthState *s) +{ + NetClientState *nc = qemu_get_queue(s->nic); + + if (open_eth_can_receive(nc)) { + qemu_flush_queued_packets(nc); + } +} + static void open_eth_ro(OpenEthState *s, uint32_t val) { } @@ -567,6 +582,7 @@ static void open_eth_moder_host_write(OpenEthState *s, uint32_t val) if (set & MODER_RXEN) { s->rx_desc = s->regs[TX_BD_NUM]; + open_eth_notify_can_receive(s); } if (set & MODER_TXEN) { s->tx_desc = 0; @@ -592,6 +608,18 @@ static void open_eth_int_mask_host_write(OpenEthState *s, uint32_t val) s->regs[INT_SOURCE] & s->regs[INT_MASK]); } +static void open_eth_tx_bd_num_host_write(OpenEthState *s, uint32_t val) +{ + if (val < 0x80) { + bool enable = s->regs[TX_BD_NUM] == 0x80; + + s->regs[TX_BD_NUM] = val; + if (enable) { + open_eth_notify_can_receive(s); + } + } +} + static void open_eth_mii_command_host_write(OpenEthState *s, uint32_t val) { unsigned fiad = GET_REGFIELD(s, MIIADDRESS, FIAD); @@ -630,6 +658,7 @@ static void open_eth_reg_write(void *opaque, [MODER] = open_eth_moder_host_write, [INT_SOURCE] = open_eth_int_source_host_write, [INT_MASK] = open_eth_int_mask_host_write, + [TX_BD_NUM] = open_eth_tx_bd_num_host_write, [MIICOMMAND] = open_eth_mii_command_host_write, [MIITX_DATA] = open_eth_mii_tx_host_write, [MIISTATUS] = open_eth_ro, -- cgit v1.1