Various fixes of Aspeed machines :

* New Supermicro X11 BMC machine (Erik)
 * Fixed valid access size on AST2400 SCU
 * Improved robustness of the ftgmac100 model.
 * New flash models in m25p80 (Igor)
 * Fixed reset sequence of SDHCI/eMMC controllers
 * Improved support of the AST2600 SDMC  (Joel)
 * Couple of SMC cleanups
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEoPZlSPBIlev+awtgUaNDx8/77KEFAl9OQPgACgkQUaNDx8/7
 7KHzsRAAmXw6963D3wIuE2Nzb1G5Zvn6nup3AsF5Xs1IZU/cLqNijiz220KslFtQ
 y8KrTO/eyBmAsEjrg1f6bWwCTZsouKq/2vWPtmTx3eU4HgeJdPbkln7E1YGmMfBR
 T4WJU6mNqkWfFT3WAW3IbB4qCoH3l0DRkgawYPWbdJmTs5CBtXOYCT14TijDVWQ5
 p8S4QjTtfRPwG9csHJ1W93t8jadTzderefkN6Zcmf9y6iOCif6SVDFvF769hzg6e
 Pzp3xxRV3ewxhSLrGdCK+fQk/IcPaLVUnh+mM3mGLk2rDQoomFXBpaz1N94rw43s
 lGuIyLkUGiHbgONmlZMXj03WWQbgGqjYpDWme1rAKJSX6CRJRixucejsRFTG5Evx
 odgY1MGNrdg0K8L0O1SQEx7O+URZZO68WrtrMTwLbOHErE7pWAR+h5RqzclwMr3v
 0hwQxDeNjhDBj+nUwoPUjXsgfVafzeywFfKuMymnygGog5hFSWiqAFIqyxj+u6YI
 HUG8kMHdLqzAgX1NWAomn2cxUEc4Q2wxDlzUgvjcvBwa6HZD+3nrjMRStHTmeVy5
 yPKWmRanXH6xIUJoRd2dMEU6SrwGjmjfnKAbG3vgxJ6B5sk4BrfKOFeaCF9M2zP6
 ZePWf6XrsPQY7aZgQRTexmXK83jqn73DOkavI2pM9s/6Ts61mdc=
 =ZQHA
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/legoater/tags/pull-aspeed-20200901' into staging

Various fixes of Aspeed machines :

* New Supermicro X11 BMC machine (Erik)
* Fixed valid access size on AST2400 SCU
* Improved robustness of the ftgmac100 model.
* New flash models in m25p80 (Igor)
* Fixed reset sequence of SDHCI/eMMC controllers
* Improved support of the AST2600 SDMC  (Joel)
* Couple of SMC cleanups

# gpg: Signature made Tue 01 Sep 2020 13:39:20 BST
# gpg:                using RSA key A0F66548F04895EBFE6B0B6051A343C7CFFBECA1
# gpg: Good signature from "Cédric Le Goater <clg@kaod.org>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: A0F6 6548 F048 95EB FE6B  0B60 51A3 43C7 CFFB ECA1

* remotes/legoater/tags/pull-aspeed-20200901:
  hw: add a number of SPI-flash's of m25p80 family
  arm: aspeed: add strap define `25HZ` of AST2500
  aspeed/smc: Open AHB window of the second chip of the AST2600 FMC controller
  aspeed/sdmc: Simplify calculation of RAM bits
  aspeed/sdmc: Allow writes to unprotected registers
  aspeed/sdmc: Perform memory training
  ftgmac100: Improve software reset
  ftgmac100: Fix integer overflow in ftgmac100_do_tx()
  ftgmac100: Check for invalid len and address before doing a DMA transfer
  ftgmac100: Change interrupt status when a DMA error occurs
  ftgmac100: Fix interrupt status "Packet moved to RX FIFO"
  ftgmac100: Fix interrupt status "Packet transmitted on ethernet"
  ftgmac100: Fix registers that can be read
  aspeed/sdhci: Fix reset sequence
  aspeed/smc: Fix max_slaves of the legacy SMC device
  aspeed/smc: Fix MemoryRegionOps definition
  hw/arm/aspeed: Add board model for Supermicro X11 BMC
  aspeed/scu: Fix valid access size on AST2400
  m25p80: Add support for n25q512ax3
  m25p80: Return the JEDEC ID twice for mx25l25635e

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-09-03 14:12:48 +01:00
commit 3dd23a4fb8
9 changed files with 208 additions and 95 deletions

View File

@ -57,6 +57,20 @@ struct AspeedMachineState {
SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \
SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT))
/* TODO: Find the actual hardware value */
#define SUPERMICROX11_BMC_HW_STRAP1 ( \
SCU_AST2400_HW_STRAP_DRAM_SIZE(DRAM_SIZE_128MB) | \
SCU_AST2400_HW_STRAP_DRAM_CONFIG(2) | \
SCU_AST2400_HW_STRAP_ACPI_DIS | \
SCU_AST2400_HW_STRAP_SET_CLK_SOURCE(AST2400_CLK_48M_IN) | \
SCU_HW_STRAP_VGA_CLASS_CODE | \
SCU_HW_STRAP_LPC_RESET_PIN | \
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_M_S_EN) | \
SCU_AST2400_HW_STRAP_SET_CPU_AHB_RATIO(AST2400_CPU_AHB_RATIO_2_1) | \
SCU_HW_STRAP_SPI_WIDTH | \
SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \
SCU_AST2400_HW_STRAP_BOOT_MODE(AST2400_SPI_BOOT))
/* AST2500 evb hardware value: 0xF100C2E6 */
#define AST2500_EVB_HW_STRAP1 (( \
AST2500_HW_STRAP1_DEFAULTS | \
@ -603,6 +617,23 @@ static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
aspeed_soc_num_cpus(amc->soc_name);
};
static void aspeed_machine_supermicrox11_bmc_class_init(ObjectClass *oc,
void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
mc->desc = "Supermicro X11 BMC (ARM926EJ-S)";
amc->soc_name = "ast2400-a1";
amc->hw_strap1 = SUPERMICROX11_BMC_HW_STRAP1;
amc->fmc_model = "mx25l25635e";
amc->spi_model = "mx25l25635e";
amc->num_cs = 1;
amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON;
amc->i2c_init = palmetto_bmc_i2c_init;
mc->default_ram_size = 256 * MiB;
}
static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@ -731,6 +762,10 @@ static const TypeInfo aspeed_machine_types[] = {
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_palmetto_class_init,
}, {
.name = MACHINE_TYPE_NAME("supermicrox11-bmc"),
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_supermicrox11_bmc_class_init,
}, {
.name = MACHINE_TYPE_NAME("ast2500-evb"),
.parent = TYPE_ASPEED_MACHINE,

View File

@ -217,8 +217,9 @@ static const FlashPartInfo known_devices[] = {
{ INFO("mx25l6405d", 0xc22017, 0, 64 << 10, 128, 0) },
{ INFO("mx25l12805d", 0xc22018, 0, 64 << 10, 256, 0) },
{ INFO("mx25l12855e", 0xc22618, 0, 64 << 10, 256, 0) },
{ INFO("mx25l25635e", 0xc22019, 0, 64 << 10, 512, 0) },
{ INFO6("mx25l25635e", 0xc22019, 0xc22019, 64 << 10, 512, 0) },
{ INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) },
{ INFO("mx66l51235f", 0xc2201a, 0, 64 << 10, 1024, ER_4K | ER_32K) },
{ INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) },
{ INFO("mx66u1g45g", 0xc2253b, 0, 64 << 10, 2048, ER_4K | ER_32K) },
{ INFO("mx66l1g45g", 0xc2201b, 0, 64 << 10, 2048, ER_4K | ER_32K) },
@ -237,6 +238,8 @@ static const FlashPartInfo known_devices[] = {
{ INFO("n25q128", 0x20ba18, 0, 64 << 10, 256, 0) },
{ INFO("n25q256a", 0x20ba19, 0, 64 << 10, 512, ER_4K) },
{ INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
{ INFO("n25q512ax3", 0x20ba20, 0x1000, 64 << 10, 1024, ER_4K) },
{ INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
{ INFO_STACKED("n25q00", 0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
{ INFO_STACKED("n25q00a", 0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
{ INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },

View File

@ -328,9 +328,10 @@ static const MemoryRegionOps aspeed_ast2400_scu_ops = {
.read = aspeed_scu_read,
.write = aspeed_ast2400_scu_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid.min_access_size = 4,
.valid.max_access_size = 4,
.valid.unaligned = false,
.valid = {
.min_access_size = 1,
.max_access_size = 4,
},
};
static const MemoryRegionOps aspeed_ast2500_scu_ops = {
@ -655,7 +656,7 @@ static const uint32_t ast2600_a1_resets[ASPEED_AST2600_SCU_NR_REGS] = {
[AST2600_SYS_RST_CTRL2] = 0xFFFFFFFC,
[AST2600_CLK_STOP_CTRL] = 0xFFFF7F8A,
[AST2600_CLK_STOP_CTRL2] = 0xFFF0FFF0,
[AST2600_SDRAM_HANDSHAKE] = 0x00000040, /* SoC completed DRAM init */
[AST2600_SDRAM_HANDSHAKE] = 0x00000000,
[AST2600_HPLL_PARAM] = 0x1000405F,
[AST2600_CHIP_ID0] = 0x1234ABCD,
[AST2600_CHIP_ID1] = 0x88884444,

View File

@ -33,15 +33,28 @@
/* Configuration Register */
#define R_CONF (0x04 / 4)
/* Interrupt control/status */
#define R_ISR (0x50 / 4)
/* Control/Status Register #1 (ast2500) */
#define R_STATUS1 (0x60 / 4)
#define PHY_BUSY_STATE BIT(0)
#define PHY_PLL_LOCK_STATUS BIT(4)
/* Reserved */
#define R_MCR6C (0x6c / 4)
#define R_ECC_TEST_CTRL (0x70 / 4)
#define ECC_TEST_FINISHED BIT(12)
#define ECC_TEST_FAIL BIT(13)
#define R_TEST_START_LEN (0x74 / 4)
#define R_TEST_FAIL_DQ (0x78 / 4)
#define R_TEST_INIT_VAL (0x7c / 4)
#define R_DRAM_SW (0x88 / 4)
#define R_DRAM_TIME (0x8c / 4)
#define R_ECC_ERR_INJECT (0xb4 / 4)
/*
* Configuration register Ox4 (for Aspeed AST2400 SOC)
*
@ -113,7 +126,7 @@ static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
if (addr >= ARRAY_SIZE(s->regs)) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
__func__, addr);
__func__, addr * 4);
return 0;
}
@ -146,57 +159,6 @@ static const MemoryRegionOps aspeed_sdmc_ops = {
.valid.max_access_size = 4,
};
static int ast2400_rambits(AspeedSDMCState *s)
{
switch (s->ram_size >> 20) {
case 64:
return ASPEED_SDMC_DRAM_64MB;
case 128:
return ASPEED_SDMC_DRAM_128MB;
case 256:
return ASPEED_SDMC_DRAM_256MB;
case 512:
return ASPEED_SDMC_DRAM_512MB;
default:
g_assert_not_reached();
break;
}
}
static int ast2500_rambits(AspeedSDMCState *s)
{
switch (s->ram_size >> 20) {
case 128:
return ASPEED_SDMC_AST2500_128MB;
case 256:
return ASPEED_SDMC_AST2500_256MB;
case 512:
return ASPEED_SDMC_AST2500_512MB;
case 1024:
return ASPEED_SDMC_AST2500_1024MB;
default:
g_assert_not_reached();
break;
}
}
static int ast2600_rambits(AspeedSDMCState *s)
{
switch (s->ram_size >> 20) {
case 256:
return ASPEED_SDMC_AST2600_256MB;
case 512:
return ASPEED_SDMC_AST2600_512MB;
case 1024:
return ASPEED_SDMC_AST2600_1024MB;
case 2048:
return ASPEED_SDMC_AST2600_2048MB;
default:
g_assert_not_reached();
break;
}
}
static void aspeed_sdmc_reset(DeviceState *dev)
{
AspeedSDMCState *s = ASPEED_SDMC(dev);
@ -206,6 +168,19 @@ static void aspeed_sdmc_reset(DeviceState *dev)
/* Set ram size bit and defaults values */
s->regs[R_CONF] = asc->compute_conf(s, 0);
/*
* PHY status:
* - set phy status ok (set bit 1)
* - initial PVT calibration ok (clear bit 3)
* - runtime calibration ok (clear bit 5)
*/
s->regs[0x100] = BIT(1);
/* PHY eye window: set all as passing */
s->regs[0x100 | (0x68 / 4)] = 0xff;
s->regs[0x100 | (0x7c / 4)] = 0xff;
s->regs[0x100 | (0x50 / 4)] = 0xfffffff;
}
static void aspeed_sdmc_get_ram_size(Object *obj, Visitor *v, const char *name,
@ -298,10 +273,32 @@ static const TypeInfo aspeed_sdmc_info = {
.abstract = true,
};
static int aspeed_sdmc_get_ram_bits(AspeedSDMCState *s)
{
AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
int i;
/*
* The bitfield value encoding the RAM size is the index of the
* possible RAM size array
*/
for (i = 0; asc->valid_ram_sizes[i]; i++) {
if (s->ram_size == asc->valid_ram_sizes[i]) {
return i;
}
}
/*
* Invalid RAM sizes should have been excluded when setting the
* SoC RAM size.
*/
g_assert_not_reached();
}
static uint32_t aspeed_2400_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
{
uint32_t fixed_conf = ASPEED_SDMC_VGA_COMPAT |
ASPEED_SDMC_DRAM_SIZE(ast2400_rambits(s));
ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
/* Make sure readonly bits are kept */
data &= ~ASPEED_SDMC_READONLY_MASK;
@ -359,7 +356,7 @@ static uint32_t aspeed_2500_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
ASPEED_SDMC_CACHE_INITIAL_DONE |
ASPEED_SDMC_DRAM_SIZE(ast2500_rambits(s));
ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
/* Make sure readonly bits are kept */
data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
@ -425,7 +422,7 @@ static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
{
uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(3) |
ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
ASPEED_SDMC_DRAM_SIZE(ast2600_rambits(s));
ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
/* Make sure readonly bits are kept (use ast2500 mask) */
data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
@ -436,6 +433,20 @@ static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
uint32_t data)
{
/* Unprotected registers */
switch (reg) {
case R_ISR:
case R_MCR6C:
case R_TEST_START_LEN:
case R_TEST_FAIL_DQ:
case R_TEST_INIT_VAL:
case R_DRAM_SW:
case R_DRAM_TIME:
case R_ECC_ERR_INJECT:
s->regs[reg] = data;
return;
}
if (s->regs[R_PROT] == PROT_HARDLOCKED) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system reset!\n",
__func__);
@ -443,7 +454,9 @@ static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
}
if (reg != R_PROT && s->regs[R_PROT] == PROT_SOFTLOCKED) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
qemu_log_mask(LOG_GUEST_ERROR,
"%s: SDMC is locked! (write to MCR%02x blocked)\n",
__func__, reg * 4);
return;
}

View File

@ -481,6 +481,37 @@ static int ftgmac100_write_bd(FTGMAC100Desc *bd, dma_addr_t addr)
return 0;
}
static int ftgmac100_insert_vlan(FTGMAC100State *s, int frame_size,
uint8_t vlan_tci)
{
uint8_t *vlan_hdr = s->frame + (ETH_ALEN * 2);
uint8_t *payload = vlan_hdr + sizeof(struct vlan_header);
if (frame_size < sizeof(struct eth_header)) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: frame too small for VLAN insertion : %d bytes\n",
__func__, frame_size);
s->isr |= FTGMAC100_INT_XPKT_LOST;
goto out;
}
if (frame_size + sizeof(struct vlan_header) > sizeof(s->frame)) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: frame too big : %d bytes\n",
__func__, frame_size);
s->isr |= FTGMAC100_INT_XPKT_LOST;
frame_size -= sizeof(struct vlan_header);
}
memmove(payload, vlan_hdr, frame_size - (ETH_ALEN * 2));
stw_be_p(vlan_hdr, ETH_P_VLAN);
stw_be_p(vlan_hdr + 2, vlan_tci);
frame_size += sizeof(struct vlan_header);
out:
return frame_size;
}
static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
uint32_t tx_descriptor)
{
@ -507,6 +538,15 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
}
len = FTGMAC100_TXDES0_TXBUF_SIZE(bd.des0);
if (!len) {
/*
* 0 is an invalid size, however the HW does not raise any
* interrupt. Flag an error because the guest is buggy.
*/
qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid segment size\n",
__func__);
}
if (frame_size + len > sizeof(s->frame)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %d bytes\n",
__func__, len);
@ -517,29 +557,21 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
if (dma_memory_read(&address_space_memory, bd.des3, ptr, len)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to read packet @ 0x%x\n",
__func__, bd.des3);
s->isr |= FTGMAC100_INT_NO_NPTXBUF;
s->isr |= FTGMAC100_INT_AHB_ERR;
break;
}
/* Check for VLAN */
if (bd.des0 & FTGMAC100_TXDES0_FTS &&
bd.des1 & FTGMAC100_TXDES1_INS_VLANTAG &&
be16_to_cpu(PKT_GET_ETH_HDR(ptr)->h_proto) != ETH_P_VLAN) {
if (frame_size + len + 4 > sizeof(s->frame)) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: frame too big : %d bytes\n",
__func__, len);
s->isr |= FTGMAC100_INT_XPKT_LOST;
len = sizeof(s->frame) - frame_size - 4;
}
memmove(ptr + 16, ptr + 12, len - 12);
stw_be_p(ptr + 12, ETH_P_VLAN);
stw_be_p(ptr + 14, bd.des1);
len += 4;
}
ptr += len;
frame_size += len;
if (bd.des0 & FTGMAC100_TXDES0_LTS) {
/* Check for VLAN */
if (flags & FTGMAC100_TXDES1_INS_VLANTAG &&
be16_to_cpu(PKT_GET_ETH_HDR(s->frame)->h_proto) != ETH_P_VLAN) {
frame_size = ftgmac100_insert_vlan(s, frame_size,
FTGMAC100_TXDES1_VLANTAG_CI(flags));
}
if (flags & FTGMAC100_TXDES1_IP_CHKSUM) {
net_checksum_calculate(s->frame, frame_size);
}
@ -547,9 +579,7 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring,
qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
ptr = s->frame;
frame_size = 0;
if (flags & FTGMAC100_TXDES1_TXIC) {
s->isr |= FTGMAC100_INT_XPKT_ETH;
}
s->isr |= FTGMAC100_INT_XPKT_ETH;
}
if (flags & FTGMAC100_TXDES1_TX2FIC) {
@ -619,10 +649,8 @@ static uint32_t ftgmac100_rxpoll(FTGMAC100State *s)
return cnt / div[speed];
}
static void ftgmac100_reset(DeviceState *d)
static void ftgmac100_do_reset(FTGMAC100State *s, bool sw_reset)
{
FTGMAC100State *s = FTGMAC100(d);
/* Reset the FTGMAC100 */
s->isr = 0;
s->ier = 0;
@ -641,7 +669,12 @@ static void ftgmac100_reset(DeviceState *d)
s->fear1 = 0;
s->tpafcr = 0xf1;
s->maccr = 0;
if (sw_reset) {
s->maccr &= FTGMAC100_MACCR_GIGA_MODE | FTGMAC100_MACCR_FAST_MODE;
} else {
s->maccr = 0;
}
s->phycr = 0;
s->phydata = 0;
s->fcr = 0x400;
@ -650,6 +683,11 @@ static void ftgmac100_reset(DeviceState *d)
phy_reset(s);
}
static void ftgmac100_reset(DeviceState *d)
{
ftgmac100_do_reset(FTGMAC100(d), false);
}
static uint64_t ftgmac100_read(void *opaque, hwaddr addr, unsigned size)
{
FTGMAC100State *s = FTGMAC100(opaque);
@ -669,6 +707,10 @@ static uint64_t ftgmac100_read(void *opaque, hwaddr addr, unsigned size)
return s->math[0];
case FTGMAC100_MATH1:
return s->math[1];
case FTGMAC100_RXR_BADR:
return s->rx_ring;
case FTGMAC100_NPTXR_BADR:
return s->tx_ring;
case FTGMAC100_ITC:
return s->itc;
case FTGMAC100_DBLAC:
@ -790,7 +832,7 @@ static void ftgmac100_write(void *opaque, hwaddr addr,
case FTGMAC100_MACCR: /* MAC Device control */
s->maccr = value;
if (value & FTGMAC100_MACCR_SW_RST) {
ftgmac100_reset(DEVICE(s));
ftgmac100_do_reset(s, true);
}
if (ftgmac100_can_receive(qemu_get_queue(s->nic))) {
@ -948,6 +990,7 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
break;
}
s->isr |= FTGMAC100_INT_RPKT_FIFO;
addr = s->rx_descriptor;
while (size > 0) {
if (!ftgmac100_can_receive(nc)) {
@ -999,8 +1042,6 @@ static ssize_t ftgmac100_receive(NetClientState *nc, const uint8_t *buf,
/* Last buffer in frame. */
bd.des0 |= flags | FTGMAC100_RXDES0_LRS;
s->isr |= FTGMAC100_INT_RPKT_BUF;
} else {
s->isr |= FTGMAC100_INT_RPKT_FIFO;
}
ftgmac100_write_bd(&bd, addr);
if (bd.des0 & s->rxdes0_edorr) {

View File

@ -16,7 +16,9 @@
#include "hw/qdev-properties.h"
#define ASPEED_SDHCI_INFO 0x00
#define ASPEED_SDHCI_INFO_RESET 0x00030000
#define ASPEED_SDHCI_INFO_SLOT1 (1 << 17)
#define ASPEED_SDHCI_INFO_SLOT0 (1 << 16)
#define ASPEED_SDHCI_INFO_RESET (1 << 0)
#define ASPEED_SDHCI_DEBOUNCE 0x04
#define ASPEED_SDHCI_DEBOUNCE_RESET 0x00000005
#define ASPEED_SDHCI_BUS 0x08
@ -67,6 +69,10 @@ static void aspeed_sdhci_write(void *opaque, hwaddr addr, uint64_t val,
AspeedSDHCIState *sdhci = opaque;
switch (addr) {
case ASPEED_SDHCI_INFO:
/* The RESET bit automatically clears. */
sdhci->regs[TO_REG(addr)] = (uint32_t)val & ~ASPEED_SDHCI_INFO_RESET;
break;
case ASPEED_SDHCI_SDIO_140:
sdhci->slots[0].capareg = (uint64_t)(uint32_t)val;
break;
@ -155,7 +161,11 @@ static void aspeed_sdhci_reset(DeviceState *dev)
AspeedSDHCIState *sdhci = ASPEED_SDHCI(dev);
memset(sdhci->regs, 0, ASPEED_SDHCI_REG_SIZE);
sdhci->regs[TO_REG(ASPEED_SDHCI_INFO)] = ASPEED_SDHCI_INFO_RESET;
sdhci->regs[TO_REG(ASPEED_SDHCI_INFO)] = ASPEED_SDHCI_INFO_SLOT0;
if (sdhci->num_slots == 2) {
sdhci->regs[TO_REG(ASPEED_SDHCI_INFO)] |= ASPEED_SDHCI_INFO_SLOT1;
}
sdhci->regs[TO_REG(ASPEED_SDHCI_DEBOUNCE)] = ASPEED_SDHCI_DEBOUNCE_RESET;
}

View File

@ -230,7 +230,7 @@ static void aspeed_smc_reg_to_segment(const AspeedSMCState *s, uint32_t reg,
static const AspeedSegments aspeed_segments_ast2600_fmc[] = {
{ 0x0, 128 * MiB }, /* start address is readonly */
{ 0x0, 0 }, /* disabled */
{ 128 * MiB, 128 * MiB }, /* default is disabled but needed for -kernel */
{ 0x0, 0 }, /* disabled */
};
@ -259,7 +259,7 @@ static const AspeedSMCController controllers[] = {
.r_timings = R_TIMINGS,
.nregs_timings = 1,
.conf_enable_w0 = CONF_ENABLE_W0,
.max_slaves = 5,
.max_slaves = 1,
.segments = aspeed_segments_legacy,
.flash_window_base = ASPEED_SOC_SMC_FLASH_BASE,
.flash_window_size = 0x6000000,
@ -1299,10 +1299,8 @@ static const MemoryRegionOps aspeed_smc_ops = {
.read = aspeed_smc_read,
.write = aspeed_smc_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid.unaligned = true,
};
/*
* Initialize the custom address spaces for DMAs
*/

View File

@ -286,6 +286,7 @@ uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
#define SCU_AST2500_HW_STRAP_ESPI_FLASH_ENABLE (0x1 << 26)
#define SCU_AST2500_HW_STRAP_ESPI_ENABLE (0x1 << 25)
#define SCU_AST2500_HW_STRAP_DDR4_ENABLE (0x1 << 24)
#define SCU_AST2500_HW_STRAP_25HZ_CLOCK_MODE (0x1 << 23)
#define SCU_AST2500_HW_STRAP_ACPI_ENABLE (0x1 << 19)
#define SCU_AST2500_HW_STRAP_USBCKI_FREQ (0x1 << 18)

View File

@ -17,7 +17,18 @@
#define TYPE_ASPEED_2500_SDMC TYPE_ASPEED_SDMC "-ast2500"
#define TYPE_ASPEED_2600_SDMC TYPE_ASPEED_SDMC "-ast2600"
#define ASPEED_SDMC_NR_REGS (0x174 >> 2)
/*
* SDMC has 174 documented registers. In addition the u-boot device tree
* describes the following regions:
* - PHY status regs at offset 0x400, length 0x200
* - PHY setting regs at offset 0x100, length 0x300
*
* There are two sets of MRS (Mode Registers) configuration in ast2600 memory
* system: one is in the SDRAM MC (memory controller) which is used in run
* time, and the other is in the DDR-PHY IP which is used during DDR-PHY
* training.
*/
#define ASPEED_SDMC_NR_REGS (0x500 >> 2)
typedef struct AspeedSDMCState {
/*< private >*/