mirror of https://gitee.com/openkylin/qemu.git
hw/arm: Add npcm7xx emc model
This is a 10/100 ethernet device that has several features. Only the ones needed by the Linux driver have been implemented. See npcm7xx_emc.c for a list of unimplemented features. Reviewed-by: Hao Wu <wuhaotsh@google.com> Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Doug Evans <dje@google.com> Message-id: 20210218212453.831406-3-dje@google.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
01c966b54f
commit
7758643650
|
@ -44,6 +44,7 @@ Supported devices
|
|||
* Analog to Digital Converter (ADC)
|
||||
* Pulse Width Modulation (PWM)
|
||||
* SMBus controller (SMBF)
|
||||
* Ethernet controller (EMC)
|
||||
|
||||
Missing devices
|
||||
---------------
|
||||
|
@ -57,7 +58,7 @@ Missing devices
|
|||
* Shared memory (SHM)
|
||||
* eSPI slave interface
|
||||
|
||||
* Ethernet controllers (GMAC and EMC)
|
||||
* Ethernet controller (GMAC)
|
||||
* USB device (USBD)
|
||||
* Peripheral SPI controller (PSPI)
|
||||
* SD/MMC host
|
||||
|
|
|
@ -82,6 +82,8 @@ enum NPCM7xxInterrupt {
|
|||
NPCM7XX_UART1_IRQ,
|
||||
NPCM7XX_UART2_IRQ,
|
||||
NPCM7XX_UART3_IRQ,
|
||||
NPCM7XX_EMC1RX_IRQ = 15,
|
||||
NPCM7XX_EMC1TX_IRQ,
|
||||
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
|
||||
NPCM7XX_TIMER1_IRQ,
|
||||
NPCM7XX_TIMER2_IRQ,
|
||||
|
@ -120,6 +122,8 @@ enum NPCM7xxInterrupt {
|
|||
NPCM7XX_SMBUS15_IRQ,
|
||||
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
|
||||
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
|
||||
NPCM7XX_EMC2RX_IRQ = 114,
|
||||
NPCM7XX_EMC2TX_IRQ,
|
||||
NPCM7XX_GPIO0_IRQ = 116,
|
||||
NPCM7XX_GPIO1_IRQ,
|
||||
NPCM7XX_GPIO2_IRQ,
|
||||
|
@ -188,6 +192,12 @@ static const hwaddr npcm7xx_smbus_addr[] = {
|
|||
0xf008f000,
|
||||
};
|
||||
|
||||
/* Register base address for each EMC Module */
|
||||
static const hwaddr npcm7xx_emc_addr[] = {
|
||||
0xf0825000,
|
||||
0xf0826000,
|
||||
};
|
||||
|
||||
static const struct {
|
||||
hwaddr regs_addr;
|
||||
uint32_t unconnected_pins;
|
||||
|
@ -406,6 +416,10 @@ static void npcm7xx_init(Object *obj)
|
|||
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
|
||||
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
|
||||
object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
|
||||
}
|
||||
}
|
||||
|
||||
static void npcm7xx_realize(DeviceState *dev, Error **errp)
|
||||
|
@ -589,6 +603,40 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
|
|||
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
|
||||
}
|
||||
|
||||
/*
|
||||
* EMC Modules. Cannot fail.
|
||||
* The mapping of the device to its netdev backend works as follows:
|
||||
* emc[i] = nd_table[i]
|
||||
* This works around the inability to specify the netdev property for the
|
||||
* emc device: it's not pluggable and thus the -device option can't be
|
||||
* used.
|
||||
*/
|
||||
QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_emc_addr) != ARRAY_SIZE(s->emc));
|
||||
QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->emc) != 2);
|
||||
for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
|
||||
s->emc[i].emc_num = i;
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->emc[i]);
|
||||
if (nd_table[i].used) {
|
||||
qemu_check_nic_model(&nd_table[i], TYPE_NPCM7XX_EMC);
|
||||
qdev_set_nic_properties(DEVICE(sbd), &nd_table[i]);
|
||||
}
|
||||
/*
|
||||
* The device exists regardless of whether it's connected to a QEMU
|
||||
* netdev backend. So always instantiate it even if there is no
|
||||
* backend.
|
||||
*/
|
||||
sysbus_realize(sbd, &error_abort);
|
||||
sysbus_mmio_map(sbd, 0, npcm7xx_emc_addr[i]);
|
||||
int tx_irq = i == 0 ? NPCM7XX_EMC1TX_IRQ : NPCM7XX_EMC2TX_IRQ;
|
||||
int rx_irq = i == 0 ? NPCM7XX_EMC1RX_IRQ : NPCM7XX_EMC2RX_IRQ;
|
||||
/*
|
||||
* N.B. The values for the second argument sysbus_connect_irq are
|
||||
* chosen to match the registration order in npcm7xx_emc_realize.
|
||||
*/
|
||||
sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, tx_irq));
|
||||
sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
|
||||
}
|
||||
|
||||
/*
|
||||
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
|
||||
* specified, but this is a programming error.
|
||||
|
@ -649,8 +697,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
|
|||
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
|
||||
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
|
||||
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
|
||||
create_unimplemented_device("npcm7xx.emc1", 0xf0825000, 4 * KiB);
|
||||
create_unimplemented_device("npcm7xx.emc2", 0xf0826000, 4 * KiB);
|
||||
create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
|
||||
create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
|
||||
create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "hw/misc/npcm7xx_gcr.h"
|
||||
#include "hw/misc/npcm7xx_pwm.h"
|
||||
#include "hw/misc/npcm7xx_rng.h"
|
||||
#include "hw/net/npcm7xx_emc.h"
|
||||
#include "hw/nvram/npcm7xx_otp.h"
|
||||
#include "hw/timer/npcm7xx_timer.h"
|
||||
#include "hw/ssi/npcm7xx_fiu.h"
|
||||
|
@ -90,6 +91,7 @@ typedef struct NPCM7xxState {
|
|||
EHCISysBusState ehci;
|
||||
OHCISysBusState ohci;
|
||||
NPCM7xxFIUState fiu[2];
|
||||
NPCM7xxEMCState emc[2];
|
||||
} NPCM7xxState;
|
||||
|
||||
#define TYPE_NPCM7XX "npcm7xx"
|
||||
|
|
Loading…
Reference in New Issue