target-arm queue:
* arm_gicv3: add missing 'break' statements * cadence_uart: protect against transmit errors * cadence_gem: avoid infinite loops with misconfigured buffer * cadence_gem: set the 'last' bit when 'wrap' is set * reenable tmp105 test case * palmetto-bmc: add ASPEED system control unit model * m25p80: add new 512Mbit and 1Gbit devices -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJXcTueAAoJEDwlJe0UNgzeXTwP/jE42NDQvFqnZ8yDR22kBxLP kWqX3Yv59Ga5CjU1WFCB8ZtpTtacZBaqsxLoyu8mRpNYpckHPrkL5cxJu1ID4t7H BJN4g1cpW3Y+NBXgR3kLsuoIoO86SvVv3FlUwYmRhEG3nEbtTD2bIDqeEg0gHoME VG4zGWldvjFF8eB+k5fyqXfXs4FJsF1BSVzOY9dvS8ealw4gUMfcx+wOPVfpa2qU kdPKqi2E9bwBDdYRfENSXHa+gKCgS8KPXue0m/R5fouPhdWozp6k2IFZu64LwqoK 4/0oDLnTnFG+dHNSABSs38QR8xfemFOjtE37VuqTGknkXJeO0CW2wCGPcvqyq09R aafYlEEfKXXxX1iimOeE+GkORPFA3VTbffAEje02gXxHjljYU3x/cbHYjW+wsuso ikUYHtqsHIrDVnPKYcwcegF19XLiFKVNg5QT/Pw0r6j0jWTAdiEpn4toC4dDfAFI L8HODvBbXgiPoqN2q6x+acfCAflczx6EN/ED6mWtfRMPmgQmnayDDRbbvWlFcDXW bIPj4OSHGv4drdTRA8wiAk0f4p3WyZtxwMXDA1MJRZnQBvCJ68lfDpBMUMk8aGVr eoSQhhZ64sI+mjl2POy3EfjLxB1MUiUGLe5bFSO1c+NbNfsEQOM1GAzxlrwZRpcq iaaQ6TqOG4sIj4UPUXNJ =TYP8 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160627' into staging target-arm queue: * arm_gicv3: add missing 'break' statements * cadence_uart: protect against transmit errors * cadence_gem: avoid infinite loops with misconfigured buffer * cadence_gem: set the 'last' bit when 'wrap' is set * reenable tmp105 test case * palmetto-bmc: add ASPEED system control unit model * m25p80: add new 512Mbit and 1Gbit devices # gpg: Signature made Mon 27 Jun 2016 15:43:42 BST # gpg: using RSA key 0x3C2525ED14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" # gpg: aka "Peter Maydell <pmaydell@gmail.com>" # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20160627: m25p80: Fix WINBOND fast read command handling m25p80: New flash devices. m25p80: Fast read commands family changes. m25p80: Introduce configuration registers. m25p80: Introduce quad and equad modes. m25p80: Add additional flash commands: m25p80: Introduce COLLECTING_VAR_LEN_DATA state. m25p80: Allow more than four banks. m25p80: Make a table for JEDEC ID. m25p80: Replace JEDEC ID masking with function. palmetto-bmc: Configure the SCU's hardware strapping register ast2400: Integrate the SCU model and set silicon revision hw/misc: Add a model for the ASPEED System Control Unit arm: Re-enable tmp105 test cadence_gem: Set the last bit when wrap is set cadence_gem: Avoid infinite loops with a misconfigured buffer cadence_uart: Protect against transmit errors hw/intc/arm_gicv3: Add missing break Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
f12103afaa
@ -24,9 +24,12 @@
|
||||
#define AST2400_IOMEM_SIZE 0x00200000
|
||||
#define AST2400_IOMEM_BASE 0x1E600000
|
||||
#define AST2400_VIC_BASE 0x1E6C0000
|
||||
#define AST2400_SCU_BASE 0x1E6E2000
|
||||
#define AST2400_TIMER_BASE 0x1E782000
|
||||
#define AST2400_I2C_BASE 0x1E78A000
|
||||
|
||||
#define AST2400_A0_SILICON_REV 0x02000303
|
||||
|
||||
static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
|
||||
static const int timer_irqs[] = { 16, 17, 18, 35, 36, 37, 38, 39, };
|
||||
|
||||
@ -72,6 +75,16 @@ static void ast2400_init(Object *obj)
|
||||
object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
|
||||
object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
|
||||
qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
|
||||
|
||||
object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
|
||||
object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
|
||||
qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
|
||||
qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
|
||||
AST2400_A0_SILICON_REV);
|
||||
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
|
||||
"hw-strap1", &error_abort);
|
||||
object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
|
||||
"hw-strap2", &error_abort);
|
||||
}
|
||||
|
||||
static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
@ -110,6 +123,14 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
|
||||
}
|
||||
|
||||
/* SCU */
|
||||
object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, AST2400_SCU_BASE);
|
||||
|
||||
/* UART - attach an 8250 to the IO space as our UART5 */
|
||||
if (serial_hds[0]) {
|
||||
qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
|
||||
|
@ -44,6 +44,8 @@ static void palmetto_bmc_init(MachineState *machine)
|
||||
&bmc->ram);
|
||||
object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
|
||||
&error_abort);
|
||||
object_property_set_int(OBJECT(&bmc->soc), 0x120CE416, "hw-strap1",
|
||||
&error_abort);
|
||||
object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
|
||||
&error_abort);
|
||||
|
||||
|
@ -53,12 +53,17 @@
|
||||
/* 16 MiB max in 3 byte address mode */
|
||||
#define MAX_3BYTES_SIZE 0x1000000
|
||||
|
||||
#define SPI_NOR_MAX_ID_LEN 6
|
||||
|
||||
typedef struct FlashPartInfo {
|
||||
const char *part_name;
|
||||
/* jedec code. (jedec >> 16) & 0xff is the 1st byte, >> 8 the 2nd etc */
|
||||
uint32_t jedec;
|
||||
/* extended jedec code */
|
||||
uint16_t ext_jedec;
|
||||
/*
|
||||
* This array stores the ID bytes.
|
||||
* The first three bytes are the JEDIC ID.
|
||||
* JEDEC ID zero means "no ID" (mostly older chips).
|
||||
*/
|
||||
uint8_t id[SPI_NOR_MAX_ID_LEN];
|
||||
uint8_t id_len;
|
||||
/* there is confusion between manufacturers as to what a sector is. In this
|
||||
* device model, a "sector" is the size that is erased by the ERASE_SECTOR
|
||||
* command (opcode 0xd8).
|
||||
@ -70,11 +75,33 @@ typedef struct FlashPartInfo {
|
||||
} FlashPartInfo;
|
||||
|
||||
/* adapted from linux */
|
||||
/* Used when the "_ext_id" is two bytes at most */
|
||||
#define INFO(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\
|
||||
.part_name = _part_name,\
|
||||
.id = {\
|
||||
((_jedec_id) >> 16) & 0xff,\
|
||||
((_jedec_id) >> 8) & 0xff,\
|
||||
(_jedec_id) & 0xff,\
|
||||
((_ext_id) >> 8) & 0xff,\
|
||||
(_ext_id) & 0xff,\
|
||||
},\
|
||||
.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),\
|
||||
.sector_size = (_sector_size),\
|
||||
.n_sectors = (_n_sectors),\
|
||||
.page_size = 256,\
|
||||
.flags = (_flags),
|
||||
|
||||
#define INFO(_part_name, _jedec, _ext_jedec, _sector_size, _n_sectors, _flags)\
|
||||
.part_name = (_part_name),\
|
||||
.jedec = (_jedec),\
|
||||
.ext_jedec = (_ext_jedec),\
|
||||
#define INFO6(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\
|
||||
.part_name = _part_name,\
|
||||
.id = {\
|
||||
((_jedec_id) >> 16) & 0xff,\
|
||||
((_jedec_id) >> 8) & 0xff,\
|
||||
(_jedec_id) & 0xff,\
|
||||
((_ext_id) >> 16) & 0xff,\
|
||||
((_ext_id) >> 8) & 0xff,\
|
||||
(_ext_id) & 0xff,\
|
||||
},\
|
||||
.id_len = 6,\
|
||||
.sector_size = (_sector_size),\
|
||||
.n_sectors = (_n_sectors),\
|
||||
.page_size = 256,\
|
||||
@ -102,12 +129,26 @@ typedef struct FlashPartInfo {
|
||||
#define EVCFG_QUAD_IO_ENABLED (1 << 7)
|
||||
#define NVCFG_4BYTE_ADDR_MASK (1 << 0)
|
||||
#define NVCFG_LOWER_SEGMENT_MASK (1 << 1)
|
||||
#define CFG_UPPER_128MB_SEG_ENABLED 0x3
|
||||
|
||||
/* Numonyx (Micron) Flag Status Register macros */
|
||||
#define FSR_4BYTE_ADDR_MODE_ENABLED 0x1
|
||||
#define FSR_FLASH_READY (1 << 7)
|
||||
|
||||
/* Spansion configuration registers macros. */
|
||||
#define SPANSION_QUAD_CFG_POS 0
|
||||
#define SPANSION_QUAD_CFG_LEN 1
|
||||
#define SPANSION_DUMMY_CLK_POS 0
|
||||
#define SPANSION_DUMMY_CLK_LEN 4
|
||||
#define SPANSION_ADDR_LEN_POS 7
|
||||
#define SPANSION_ADDR_LEN_LEN 1
|
||||
|
||||
/*
|
||||
* Spansion read mode command length in bytes,
|
||||
* the mode is currently not supported.
|
||||
*/
|
||||
|
||||
#define SPANSION_CONTINUOUS_READ_MODE_CMD_LEN 1
|
||||
|
||||
static const FlashPartInfo known_devices[] = {
|
||||
/* Atmel -- some are (confusingly) marketed as "DataFlash" */
|
||||
{ INFO("at25fs010", 0x1f6601, 0, 32 << 10, 4, ER_4K) },
|
||||
@ -158,6 +199,8 @@ static const FlashPartInfo known_devices[] = {
|
||||
{ INFO("mx25l12855e", 0xc22618, 0, 64 << 10, 256, 0) },
|
||||
{ INFO("mx25l25635e", 0xc22019, 0, 64 << 10, 512, 0) },
|
||||
{ INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) },
|
||||
{ INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) },
|
||||
{ INFO("mx66u1g45g", 0xc2253b, 0, 64 << 10, 2048, ER_4K | ER_32K) },
|
||||
|
||||
/* Micron */
|
||||
{ INFO("n25q032a11", 0x20bb16, 0, 64 << 10, 64, ER_4K) },
|
||||
@ -168,6 +211,11 @@ static const FlashPartInfo known_devices[] = {
|
||||
{ INFO("n25q128a13", 0x20ba18, 0, 64 << 10, 256, ER_4K) },
|
||||
{ INFO("n25q256a11", 0x20bb19, 0, 64 << 10, 512, ER_4K) },
|
||||
{ INFO("n25q256a13", 0x20ba19, 0, 64 << 10, 512, ER_4K) },
|
||||
{ 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("mt25ql01g", 0x20ba21, 0, 64 << 10, 2048, ER_4K) },
|
||||
{ INFO("mt25qu01g", 0x20bb21, 0, 64 << 10, 2048, ER_4K) },
|
||||
|
||||
/* Spansion -- single (large) sector size only, at least
|
||||
* for the chips listed here (without boot sectors).
|
||||
@ -176,8 +224,8 @@ static const FlashPartInfo known_devices[] = {
|
||||
{ INFO("s25sl064p", 0x010216, 0x4d00, 64 << 10, 128, ER_4K) },
|
||||
{ INFO("s25fl256s0", 0x010219, 0x4d00, 256 << 10, 128, 0) },
|
||||
{ INFO("s25fl256s1", 0x010219, 0x4d01, 64 << 10, 512, 0) },
|
||||
{ INFO("s25fl512s", 0x010220, 0x4d00, 256 << 10, 256, 0) },
|
||||
{ INFO("s70fl01gs", 0x010221, 0x4d00, 256 << 10, 256, 0) },
|
||||
{ INFO6("s25fl512s", 0x010220, 0x4d0080, 256 << 10, 256, 0) },
|
||||
{ INFO6("s70fl01gs", 0x010221, 0x4d0080, 256 << 10, 512, 0) },
|
||||
{ INFO("s25sl12800", 0x012018, 0x0300, 256 << 10, 64, 0) },
|
||||
{ INFO("s25sl12801", 0x012018, 0x0301, 64 << 10, 256, 0) },
|
||||
{ INFO("s25fl129p0", 0x012018, 0x4d00, 256 << 10, 64, 0) },
|
||||
@ -190,6 +238,10 @@ static const FlashPartInfo known_devices[] = {
|
||||
{ INFO("s25fl016k", 0xef4015, 0, 64 << 10, 32, ER_4K | ER_32K) },
|
||||
{ INFO("s25fl064k", 0xef4017, 0, 64 << 10, 128, ER_4K | ER_32K) },
|
||||
|
||||
/* Spansion -- boot sectors support */
|
||||
{ INFO6("s25fs512s", 0x010220, 0x4d0081, 256 << 10, 256, 0) },
|
||||
{ INFO6("s70fs01gs", 0x010221, 0x4d0081, 256 << 10, 512, 0) },
|
||||
|
||||
/* SST -- large erase sizes are "overlays", "sectors" are 4<< 10 */
|
||||
{ INFO("sst25vf040b", 0xbf258d, 0, 64 << 10, 8, ER_4K) },
|
||||
{ INFO("sst25vf080b", 0xbf258e, 0, 64 << 10, 16, ER_4K) },
|
||||
@ -240,10 +292,6 @@ static const FlashPartInfo known_devices[] = {
|
||||
{ INFO("w25q80", 0xef5014, 0, 64 << 10, 16, ER_4K) },
|
||||
{ INFO("w25q80bl", 0xef4014, 0, 64 << 10, 16, ER_4K) },
|
||||
{ INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K) },
|
||||
|
||||
{ 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) },
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@ -255,6 +303,7 @@ typedef enum {
|
||||
JEDEC_READ = 0x9f,
|
||||
BULK_ERASE = 0xc7,
|
||||
READ_FSR = 0x70,
|
||||
RDCR = 0x15,
|
||||
|
||||
READ = 0x03,
|
||||
READ4 = 0x13,
|
||||
@ -271,12 +320,14 @@ typedef enum {
|
||||
|
||||
PP = 0x02,
|
||||
PP4 = 0x12,
|
||||
PP4_4 = 0x3e,
|
||||
DPP = 0xa2,
|
||||
QPP = 0x32,
|
||||
|
||||
ERASE_4K = 0x20,
|
||||
ERASE4_4K = 0x21,
|
||||
ERASE_32K = 0x52,
|
||||
ERASE4_32K = 0x5c,
|
||||
ERASE_SECTOR = 0xd8,
|
||||
ERASE4_SECTOR = 0xdc,
|
||||
|
||||
@ -289,6 +340,13 @@ typedef enum {
|
||||
RESET_ENABLE = 0x66,
|
||||
RESET_MEMORY = 0x99,
|
||||
|
||||
/*
|
||||
* Micron: 0x35 - enable QPI
|
||||
* Spansion: 0x35 - read control register
|
||||
*/
|
||||
RDCR_EQIO = 0x35,
|
||||
RSTQIO = 0xf5,
|
||||
|
||||
RNVCR = 0xB5,
|
||||
WNVCR = 0xB1,
|
||||
|
||||
@ -304,9 +362,18 @@ typedef enum {
|
||||
STATE_PAGE_PROGRAM,
|
||||
STATE_READ,
|
||||
STATE_COLLECTING_DATA,
|
||||
STATE_COLLECTING_VAR_LEN_DATA,
|
||||
STATE_READING_DATA,
|
||||
} CMDState;
|
||||
|
||||
typedef enum {
|
||||
MAN_SPANSION,
|
||||
MAN_MACRONIX,
|
||||
MAN_NUMONYX,
|
||||
MAN_WINBOND,
|
||||
MAN_GENERIC,
|
||||
} Manufacturer;
|
||||
|
||||
typedef struct Flash {
|
||||
SSISlave parent_obj;
|
||||
|
||||
@ -324,11 +391,22 @@ typedef struct Flash {
|
||||
uint8_t cmd_in_progress;
|
||||
uint64_t cur_addr;
|
||||
uint32_t nonvolatile_cfg;
|
||||
/* Configuration register for Macronix */
|
||||
uint32_t volatile_cfg;
|
||||
uint32_t enh_volatile_cfg;
|
||||
/* Spansion cfg registers. */
|
||||
uint8_t spansion_cr1nv;
|
||||
uint8_t spansion_cr2nv;
|
||||
uint8_t spansion_cr3nv;
|
||||
uint8_t spansion_cr4nv;
|
||||
uint8_t spansion_cr1v;
|
||||
uint8_t spansion_cr2v;
|
||||
uint8_t spansion_cr3v;
|
||||
uint8_t spansion_cr4v;
|
||||
bool write_enable;
|
||||
bool four_bytes_address_mode;
|
||||
bool reset_enable;
|
||||
bool quad_enable;
|
||||
uint8_t ear;
|
||||
|
||||
int64_t dirty_page;
|
||||
@ -350,6 +428,22 @@ typedef struct M25P80Class {
|
||||
#define M25P80_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(M25P80Class, (obj), TYPE_M25P80)
|
||||
|
||||
static inline Manufacturer get_man(Flash *s)
|
||||
{
|
||||
switch (s->pi->id[0]) {
|
||||
case 0x20:
|
||||
return MAN_NUMONYX;
|
||||
case 0xEF:
|
||||
return MAN_WINBOND;
|
||||
case 0x01:
|
||||
return MAN_SPANSION;
|
||||
case 0xC2:
|
||||
return MAN_MACRONIX;
|
||||
default:
|
||||
return MAN_GENERIC;
|
||||
}
|
||||
}
|
||||
|
||||
static void blk_sync_complete(void *opaque, int ret)
|
||||
{
|
||||
/* do nothing. Masters do not directly interact with the backing store,
|
||||
@ -398,6 +492,7 @@ static void flash_erase(Flash *s, int offset, FlashCMD cmd)
|
||||
capa_to_assert = ER_4K;
|
||||
break;
|
||||
case ERASE_32K:
|
||||
case ERASE4_32K:
|
||||
len = 32 << 10;
|
||||
capa_to_assert = ER_32K;
|
||||
break;
|
||||
@ -468,9 +563,11 @@ static inline int get_addr_length(Flash *s)
|
||||
|
||||
switch (s->cmd_in_progress) {
|
||||
case PP4:
|
||||
case PP4_4:
|
||||
case READ4:
|
||||
case QIOR4:
|
||||
case ERASE4_4K:
|
||||
case ERASE4_32K:
|
||||
case ERASE4_SECTOR:
|
||||
case FAST_READ4:
|
||||
case DOR4:
|
||||
@ -494,7 +591,7 @@ static void complete_collecting_data(Flash *s)
|
||||
}
|
||||
|
||||
if (get_addr_length(s) == 3) {
|
||||
s->cur_addr += (s->ear & 0x3) * MAX_3BYTES_SIZE;
|
||||
s->cur_addr += s->ear * MAX_3BYTES_SIZE;
|
||||
}
|
||||
|
||||
s->state = STATE_IDLE;
|
||||
@ -504,6 +601,7 @@ static void complete_collecting_data(Flash *s)
|
||||
case QPP:
|
||||
case PP:
|
||||
case PP4:
|
||||
case PP4_4:
|
||||
s->state = STATE_PAGE_PROGRAM;
|
||||
break;
|
||||
case READ:
|
||||
@ -523,11 +621,25 @@ static void complete_collecting_data(Flash *s)
|
||||
case ERASE_4K:
|
||||
case ERASE4_4K:
|
||||
case ERASE_32K:
|
||||
case ERASE4_32K:
|
||||
case ERASE_SECTOR:
|
||||
case ERASE4_SECTOR:
|
||||
flash_erase(s, s->cur_addr, s->cmd_in_progress);
|
||||
break;
|
||||
case WRSR:
|
||||
switch (get_man(s)) {
|
||||
case MAN_SPANSION:
|
||||
s->quad_enable = !!(s->data[1] & 0x02);
|
||||
break;
|
||||
case MAN_MACRONIX:
|
||||
s->quad_enable = extract32(s->data[0], 6, 1);
|
||||
if (s->len > 1) {
|
||||
s->four_bytes_address_mode = extract32(s->data[1], 5, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (s->write_enable) {
|
||||
s->write_enable = false;
|
||||
}
|
||||
@ -561,8 +673,10 @@ static void reset_memory(Flash *s)
|
||||
s->state = STATE_IDLE;
|
||||
s->write_enable = false;
|
||||
s->reset_enable = false;
|
||||
s->quad_enable = false;
|
||||
|
||||
if (((s->pi->jedec >> 16) & 0xFF) == JEDEC_NUMONYX) {
|
||||
switch (get_man(s)) {
|
||||
case MAN_NUMONYX:
|
||||
s->volatile_cfg = 0;
|
||||
s->volatile_cfg |= VCFG_DUMMY;
|
||||
s->volatile_cfg |= VCFG_WRAP_SEQUENTIAL;
|
||||
@ -592,16 +706,147 @@ static void reset_memory(Flash *s)
|
||||
s->four_bytes_address_mode = true;
|
||||
}
|
||||
if (!(s->nonvolatile_cfg & NVCFG_LOWER_SEGMENT_MASK)) {
|
||||
s->ear = CFG_UPPER_128MB_SEG_ENABLED;
|
||||
s->ear = s->size / MAX_3BYTES_SIZE - 1;
|
||||
}
|
||||
break;
|
||||
case MAN_MACRONIX:
|
||||
s->volatile_cfg = 0x7;
|
||||
break;
|
||||
case MAN_SPANSION:
|
||||
s->spansion_cr1v = s->spansion_cr1nv;
|
||||
s->spansion_cr2v = s->spansion_cr2nv;
|
||||
s->spansion_cr3v = s->spansion_cr3nv;
|
||||
s->spansion_cr4v = s->spansion_cr4nv;
|
||||
s->quad_enable = extract32(s->spansion_cr1v,
|
||||
SPANSION_QUAD_CFG_POS,
|
||||
SPANSION_QUAD_CFG_LEN
|
||||
);
|
||||
s->four_bytes_address_mode = extract32(s->spansion_cr2v,
|
||||
SPANSION_ADDR_LEN_POS,
|
||||
SPANSION_ADDR_LEN_LEN
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
DB_PRINT_L(0, "Reset done.\n");
|
||||
}
|
||||
|
||||
static void decode_fast_read_cmd(Flash *s)
|
||||
{
|
||||
s->needed_bytes = get_addr_length(s);
|
||||
switch (get_man(s)) {
|
||||
/* Dummy cycles - modeled with bytes writes instead of bits */
|
||||
case MAN_WINBOND:
|
||||
s->needed_bytes += 8;
|
||||
break;
|
||||
case MAN_NUMONYX:
|
||||
s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
|
||||
break;
|
||||
case MAN_MACRONIX:
|
||||
if (extract32(s->volatile_cfg, 6, 2) == 1) {
|
||||
s->needed_bytes += 6;
|
||||
} else {
|
||||
s->needed_bytes += 8;
|
||||
}
|
||||
break;
|
||||
case MAN_SPANSION:
|
||||
s->needed_bytes += extract32(s->spansion_cr2v,
|
||||
SPANSION_DUMMY_CLK_POS,
|
||||
SPANSION_DUMMY_CLK_LEN
|
||||
);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
}
|
||||
|
||||
static void decode_dio_read_cmd(Flash *s)
|
||||
{
|
||||
s->needed_bytes = get_addr_length(s);
|
||||
/* Dummy cycles modeled with bytes writes instead of bits */
|
||||
switch (get_man(s)) {
|
||||
case MAN_WINBOND:
|
||||
s->needed_bytes += 8;
|
||||
break;
|
||||
case MAN_SPANSION:
|
||||
s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
|
||||
s->needed_bytes += extract32(s->spansion_cr2v,
|
||||
SPANSION_DUMMY_CLK_POS,
|
||||
SPANSION_DUMMY_CLK_LEN
|
||||
);
|
||||
break;
|
||||
case MAN_NUMONYX:
|
||||
s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
|
||||
break;
|
||||
case MAN_MACRONIX:
|
||||
switch (extract32(s->volatile_cfg, 6, 2)) {
|
||||
case 1:
|
||||
s->needed_bytes += 6;
|
||||
break;
|
||||
case 2:
|
||||
s->needed_bytes += 8;
|
||||
break;
|
||||
default:
|
||||
s->needed_bytes += 4;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
}
|
||||
|
||||
static void decode_qio_read_cmd(Flash *s)
|
||||
{
|
||||
s->needed_bytes = get_addr_length(s);
|
||||
/* Dummy cycles modeled with bytes writes instead of bits */
|
||||
switch (get_man(s)) {
|
||||
case MAN_WINBOND:
|
||||
s->needed_bytes += 8;
|
||||
break;
|
||||
case MAN_SPANSION:
|
||||
s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
|
||||
s->needed_bytes += extract32(s->spansion_cr2v,
|
||||
SPANSION_DUMMY_CLK_POS,
|
||||
SPANSION_DUMMY_CLK_LEN
|
||||
);
|
||||
break;
|
||||
case MAN_NUMONYX:
|
||||
s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
|
||||
break;
|
||||
case MAN_MACRONIX:
|
||||
switch (extract32(s->volatile_cfg, 6, 2)) {
|
||||
case 1:
|
||||
s->needed_bytes += 4;
|
||||
break;
|
||||
case 2:
|
||||
s->needed_bytes += 8;
|
||||
break;
|
||||
default:
|
||||
s->needed_bytes += 6;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
}
|
||||
|
||||
static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
{
|
||||
s->cmd_in_progress = value;
|
||||
int i;
|
||||
DB_PRINT_L(0, "decoded new command:%x\n", value);
|
||||
|
||||
if (value != RESET_MEMORY) {
|
||||
@ -613,6 +858,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
case ERASE_4K:
|
||||
case ERASE4_4K:
|
||||
case ERASE_32K:
|
||||
case ERASE4_32K:
|
||||
case ERASE_SECTOR:
|
||||
case ERASE4_SECTOR:
|
||||
case READ:
|
||||
@ -621,6 +867,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
case QPP:
|
||||
case PP:
|
||||
case PP4:
|
||||
case PP4_4:
|
||||
s->needed_bytes = get_addr_length(s);
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
@ -633,56 +880,35 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
case DOR4:
|
||||
case QOR:
|
||||
case QOR4:
|
||||
s->needed_bytes = get_addr_length(s);
|
||||
if (((s->pi->jedec >> 16) & 0xFF) == JEDEC_NUMONYX) {
|
||||
/* Dummy cycles modeled with bytes writes instead of bits */
|
||||
s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
|
||||
}
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
decode_fast_read_cmd(s);
|
||||
break;
|
||||
|
||||
case DIOR:
|
||||
case DIOR4:
|
||||
switch ((s->pi->jedec >> 16) & 0xFF) {
|
||||
case JEDEC_WINBOND:
|
||||
case JEDEC_SPANSION:
|
||||
s->needed_bytes = 4;
|
||||
break;
|
||||
default:
|
||||
s->needed_bytes = get_addr_length(s);
|
||||
/* Dummy cycles modeled with bytes writes instead of bits */
|
||||
s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
|
||||
}
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
decode_dio_read_cmd(s);
|
||||
break;
|
||||
|
||||
case QIOR:
|
||||
case QIOR4:
|
||||
switch ((s->pi->jedec >> 16) & 0xFF) {
|
||||
case JEDEC_WINBOND:
|
||||
case JEDEC_SPANSION:
|
||||
s->needed_bytes = 6;
|
||||
break;
|
||||
default:
|
||||
s->needed_bytes = get_addr_length(s);
|
||||
/* Dummy cycles modeled with bytes writes instead of bits */
|
||||
s->needed_bytes += extract32(s->volatile_cfg, 4, 4);
|
||||
}
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
decode_qio_read_cmd(s);
|
||||
break;
|
||||
|
||||
case WRSR:
|
||||
if (s->write_enable) {
|
||||
s->needed_bytes = 1;
|
||||
switch (get_man(s)) {
|
||||
case MAN_SPANSION:
|
||||
s->needed_bytes = 2;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
break;
|
||||
case MAN_MACRONIX:
|
||||
s->needed_bytes = 2;
|
||||
s->state = STATE_COLLECTING_VAR_LEN_DATA;
|
||||
break;
|
||||
default:
|
||||
s->needed_bytes = 1;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
}
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
s->state = STATE_COLLECTING_DATA;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -695,6 +921,9 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
|
||||
case RDSR:
|
||||
s->data[0] = (!!s->write_enable) << 1;
|
||||
if (get_man(s) == MAN_MACRONIX) {
|
||||
s->data[0] |= (!!s->quad_enable) << 6;
|
||||
}
|
||||
s->pos = 0;
|
||||
s->len = 1;
|
||||
s->state = STATE_READING_DATA;
|
||||
@ -712,20 +941,23 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
|
||||
case JEDEC_READ:
|
||||
DB_PRINT_L(0, "populated jedec code\n");
|
||||
s->data[0] = (s->pi->jedec >> 16) & 0xff;
|
||||
s->data[1] = (s->pi->jedec >> 8) & 0xff;
|
||||
s->data[2] = s->pi->jedec & 0xff;
|
||||
if (s->pi->ext_jedec) {
|
||||
s->data[3] = (s->pi->ext_jedec >> 8) & 0xff;
|
||||
s->data[4] = s->pi->ext_jedec & 0xff;
|
||||
s->len = 5;
|
||||
} else {
|
||||
s->len = 3;
|
||||
for (i = 0; i < s->pi->id_len; i++) {
|
||||
s->data[i] = s->pi->id[i];
|
||||
}
|
||||
|
||||
s->len = s->pi->id_len;
|
||||
s->pos = 0;
|
||||
s->state = STATE_READING_DATA;
|
||||
break;
|
||||
|
||||
case RDCR:
|
||||
s->data[0] = s->volatile_cfg & 0xFF;
|
||||
s->data[0] |= (!!s->four_bytes_address_mode) << 5;
|
||||
s->pos = 0;
|
||||
s->len = 1;
|
||||
s->state = STATE_READING_DATA;
|
||||
break;
|
||||
|
||||
case BULK_ERASE:
|
||||
if (s->write_enable) {
|
||||
DB_PRINT_L(0, "chip erase\n");
|
||||
@ -765,7 +997,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
s->state = STATE_READING_DATA;
|
||||
break;
|
||||
case WNVCR:
|
||||
if (s->write_enable) {
|
||||
if (s->write_enable && get_man(s) == MAN_NUMONYX) {
|
||||
s->needed_bytes = 2;
|
||||
s->pos = 0;
|
||||
s->len = 0;
|
||||
@ -808,6 +1040,24 @@ static void decode_new_cmd(Flash *s, uint32_t value)
|
||||
reset_memory(s);
|
||||
}
|
||||
break;
|
||||
case RDCR_EQIO:
|
||||
switch (get_man(s)) {
|
||||
case MAN_SPANSION:
|
||||
s->data[0] = (!!s->quad_enable) << 1;
|
||||
s->pos = 0;
|
||||
s->len = 1;
|
||||
s->state = STATE_READING_DATA;
|
||||
break;
|
||||
case MAN_MACRONIX:
|
||||
s->quad_enable = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RSTQIO:
|
||||
s->quad_enable = false;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
|
||||
break;
|
||||
@ -819,6 +1069,9 @@ static int m25p80_cs(SSISlave *ss, bool select)
|
||||
Flash *s = M25P80(ss);
|
||||
|
||||
if (select) {
|
||||
if (s->state == STATE_COLLECTING_VAR_LEN_DATA) {
|
||||
complete_collecting_data(s);
|
||||
}
|
||||
s->len = 0;
|
||||
s->pos = 0;
|
||||
s->state = STATE_IDLE;
|
||||
@ -852,6 +1105,7 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
|
||||
break;
|
||||
|
||||
case STATE_COLLECTING_DATA:
|
||||
case STATE_COLLECTING_VAR_LEN_DATA:
|
||||
s->data[s->len] = (uint8_t)tx;
|
||||
s->len++;
|
||||
|
||||
@ -926,13 +1180,18 @@ static void m25p80_pre_save(void *opaque)
|
||||
}
|
||||
|
||||
static Property m25p80_properties[] = {
|
||||
/* This is default value for Micron flash */
|
||||
DEFINE_PROP_UINT32("nonvolatile-cfg", Flash, nonvolatile_cfg, 0x8FFF),
|
||||
DEFINE_PROP_UINT8("spansion-cr1nv", Flash, spansion_cr1nv, 0x0),
|
||||
DEFINE_PROP_UINT8("spansion-cr2nv", Flash, spansion_cr2nv, 0x8),
|
||||
DEFINE_PROP_UINT8("spansion-cr3nv", Flash, spansion_cr3nv, 0x2),
|
||||
DEFINE_PROP_UINT8("spansion-cr4nv", Flash, spansion_cr4nv, 0x10),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static const VMStateDescription vmstate_m25p80 = {
|
||||
.name = "xilinx_spi",
|
||||
.version_id = 2,
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 1,
|
||||
.pre_save = m25p80_pre_save,
|
||||
.fields = (VMStateField[]) {
|
||||
@ -950,6 +1209,11 @@ static const VMStateDescription vmstate_m25p80 = {
|
||||
VMSTATE_UINT32_V(nonvolatile_cfg, Flash, 2),
|
||||
VMSTATE_UINT32_V(volatile_cfg, Flash, 2),
|
||||
VMSTATE_UINT32_V(enh_volatile_cfg, Flash, 2),
|
||||
VMSTATE_BOOL_V(quad_enable, Flash, 3),
|
||||
VMSTATE_UINT8_V(spansion_cr1nv, Flash, 3),
|
||||
VMSTATE_UINT8_V(spansion_cr2nv, Flash, 3),
|
||||
VMSTATE_UINT8_V(spansion_cr3nv, Flash, 3),
|
||||
VMSTATE_UINT8_V(spansion_cr4nv, Flash, 3),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
@ -288,8 +288,11 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond,
|
||||
}
|
||||
|
||||
ret = qemu_chr_fe_write(s->chr, s->tx_fifo, s->tx_count);
|
||||
s->tx_count -= ret;
|
||||
memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_count);
|
||||
|
||||
if (ret >= 0) {
|
||||
s->tx_count -= ret;
|
||||
memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_count);
|
||||
}
|
||||
|
||||
if (s->tx_count) {
|
||||
int r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP,
|
||||
|
@ -975,6 +975,7 @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env,
|
||||
if (!is_a64(env) && !arm_is_el3_or_mon(env)) {
|
||||
r = CP_ACCESS_TRAP_EL3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
@ -1006,6 +1007,7 @@ static CPAccessResult gicv3_fiq_access(CPUARMState *env,
|
||||
if (!is_a64(env) && !arm_is_el3_or_mon(env)) {
|
||||
r = CP_ACCESS_TRAP_EL3;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
@ -52,3 +52,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
|
||||
obj-$(CONFIG_EDU) += edu.o
|
||||
obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
|
||||
obj-$(CONFIG_AUX) += aux.o
|
||||
obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o
|
||||
|
283
hw/misc/aspeed_scu.c
Normal file
283
hw/misc/aspeed_scu.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* ASPEED System Control Unit
|
||||
*
|
||||
* Andrew Jeffery <andrew@aj.id.au>
|
||||
*
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* This code is licensed under the GPL version 2 or later. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/misc/aspeed_scu.h"
|
||||
#include "hw/qdev-properties.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "trace.h"
|
||||
|
||||
#define TO_REG(offset) ((offset) >> 2)
|
||||
|
||||
#define PROT_KEY TO_REG(0x00)
|
||||
#define SYS_RST_CTRL TO_REG(0x04)
|
||||
#define CLK_SEL TO_REG(0x08)
|
||||
#define CLK_STOP_CTRL TO_REG(0x0C)
|
||||
#define FREQ_CNTR_CTRL TO_REG(0x10)
|
||||
#define FREQ_CNTR_EVAL TO_REG(0x14)
|
||||
#define IRQ_CTRL TO_REG(0x18)
|
||||
#define D2PLL_PARAM TO_REG(0x1C)
|
||||
#define MPLL_PARAM TO_REG(0x20)
|
||||
#define HPLL_PARAM TO_REG(0x24)
|
||||
#define FREQ_CNTR_RANGE TO_REG(0x28)
|
||||
#define MISC_CTRL1 TO_REG(0x2C)
|
||||
#define PCI_CTRL1 TO_REG(0x30)
|
||||
#define PCI_CTRL2 TO_REG(0x34)
|
||||
#define PCI_CTRL3 TO_REG(0x38)
|
||||
#define SYS_RST_STATUS TO_REG(0x3C)
|
||||
#define SOC_SCRATCH1 TO_REG(0x40)
|
||||
#define SOC_SCRATCH2 TO_REG(0x44)
|
||||
#define MAC_CLK_DELAY TO_REG(0x48)
|
||||
#define MISC_CTRL2 TO_REG(0x4C)
|
||||
#define VGA_SCRATCH1 TO_REG(0x50)
|
||||
#define VGA_SCRATCH2 TO_REG(0x54)
|
||||
#define VGA_SCRATCH3 TO_REG(0x58)
|
||||
#define VGA_SCRATCH4 TO_REG(0x5C)
|
||||
#define VGA_SCRATCH5 TO_REG(0x60)
|
||||
#define VGA_SCRATCH6 TO_REG(0x64)
|
||||
#define VGA_SCRATCH7 TO_REG(0x68)
|
||||
#define VGA_SCRATCH8 TO_REG(0x6C)
|
||||
#define HW_STRAP1 TO_REG(0x70)
|
||||
#define RNG_CTRL TO_REG(0x74)
|
||||
#define RNG_DATA TO_REG(0x78)
|
||||
#define SILICON_REV TO_REG(0x7C)
|
||||
#define PINMUX_CTRL1 TO_REG(0x80)
|
||||
#define PINMUX_CTRL2 TO_REG(0x84)
|
||||
#define PINMUX_CTRL3 TO_REG(0x88)
|
||||
#define PINMUX_CTRL4 TO_REG(0x8C)
|
||||
#define PINMUX_CTRL5 TO_REG(0x90)
|
||||
#define PINMUX_CTRL6 TO_REG(0x94)
|
||||
#define WDT_RST_CTRL TO_REG(0x9C)
|
||||
#define PINMUX_CTRL7 TO_REG(0xA0)
|
||||
#define PINMUX_CTRL8 TO_REG(0xA4)
|
||||
#define PINMUX_CTRL9 TO_REG(0xA8)
|
||||
#define WAKEUP_EN TO_REG(0xC0)
|
||||
#define WAKEUP_CTRL TO_REG(0xC4)
|
||||
#define HW_STRAP2 TO_REG(0xD0)
|
||||
#define FREE_CNTR4 TO_REG(0xE0)
|
||||
#define FREE_CNTR4_EXT TO_REG(0xE4)
|
||||
#define CPU2_CTRL TO_REG(0x100)
|
||||
#define CPU2_BASE_SEG1 TO_REG(0x104)
|
||||
#define CPU2_BASE_SEG2 TO_REG(0x108)
|
||||
#define CPU2_BASE_SEG3 TO_REG(0x10C)
|
||||
#define CPU2_BASE_SEG4 TO_REG(0x110)
|
||||
#define CPU2_BASE_SEG5 TO_REG(0x114)
|
||||
#define CPU2_CACHE_CTRL TO_REG(0x118)
|
||||
#define UART_HPLL_CLK TO_REG(0x160)
|
||||
#define PCIE_CTRL TO_REG(0x180)
|
||||
#define BMC_MMIO_CTRL TO_REG(0x184)
|
||||
#define RELOC_DECODE_BASE1 TO_REG(0x188)
|
||||
#define RELOC_DECODE_BASE2 TO_REG(0x18C)
|
||||
#define MAILBOX_DECODE_BASE TO_REG(0x190)
|
||||
#define SRAM_DECODE_BASE1 TO_REG(0x194)
|
||||
#define SRAM_DECODE_BASE2 TO_REG(0x198)
|
||||
#define BMC_REV TO_REG(0x19C)
|
||||
#define BMC_DEV_ID TO_REG(0x1A4)
|
||||
|
||||
#define PROT_KEY_UNLOCK 0x1688A8A8
|
||||
#define SCU_IO_REGION_SIZE 0x20000
|
||||
|
||||
#define AST2400_A0_SILICON_REV 0x02000303U
|
||||
|
||||
static const uint32_t ast2400_a0_resets[ASPEED_SCU_NR_REGS] = {
|
||||
[SYS_RST_CTRL] = 0xFFCFFEDCU,
|
||||
[CLK_SEL] = 0xF3F40000U,
|
||||
[CLK_STOP_CTRL] = 0x19FC3E8BU,
|
||||
[D2PLL_PARAM] = 0x00026108U,
|
||||
[MPLL_PARAM] = 0x00030291U,
|
||||
[HPLL_PARAM] = 0x00000291U,
|
||||
[MISC_CTRL1] = 0x00000010U,
|
||||
[PCI_CTRL1] = 0x20001A03U,
|
||||
[PCI_CTRL2] = 0x20001A03U,
|
||||
[PCI_CTRL3] = 0x04000030U,
|
||||
[SYS_RST_STATUS] = 0x00000001U,
|
||||
[SOC_SCRATCH1] = 0x000000C0U, /* SoC completed DRAM init */
|
||||
[MISC_CTRL2] = 0x00000023U,
|
||||
[RNG_CTRL] = 0x0000000EU,
|
||||
[PINMUX_CTRL2] = 0x0000F000U,
|
||||
[PINMUX_CTRL3] = 0x01000000U,
|
||||
[PINMUX_CTRL4] = 0x000000FFU,
|
||||
[PINMUX_CTRL5] = 0x0000A000U,
|
||||
[WDT_RST_CTRL] = 0x003FFFF3U,
|
||||
[PINMUX_CTRL8] = 0xFFFF0000U,
|
||||
[PINMUX_CTRL9] = 0x000FFFFFU,
|
||||
[FREE_CNTR4] = 0x000000FFU,
|
||||
[FREE_CNTR4_EXT] = 0x000000FFU,
|
||||
[CPU2_BASE_SEG1] = 0x80000000U,
|
||||
[CPU2_BASE_SEG4] = 0x1E600000U,
|
||||
[CPU2_BASE_SEG5] = 0xC0000000U,
|
||||
[UART_HPLL_CLK] = 0x00001903U,
|
||||
[PCIE_CTRL] = 0x0000007BU,
|
||||
[BMC_DEV_ID] = 0x00002402U
|
||||
};
|
||||
|
||||
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
int reg = TO_REG(offset);
|
||||
|
||||
if (reg >= ARRAY_SIZE(s->regs)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (reg) {
|
||||
case WAKEUP_EN:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Read of write-only offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
return s->regs[reg];
|
||||
}
|
||||
|
||||
static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
|
||||
unsigned size)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(opaque);
|
||||
int reg = TO_REG(offset);
|
||||
|
||||
if (reg >= ARRAY_SIZE(s->regs)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reg > PROT_KEY && reg < CPU2_BASE_SEG1 &&
|
||||
s->regs[PROT_KEY] != PROT_KEY_UNLOCK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: SCU is locked!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
trace_aspeed_scu_write(offset, size, data);
|
||||
|
||||
switch (reg) {
|
||||
case FREQ_CNTR_EVAL:
|
||||
case VGA_SCRATCH1 ... VGA_SCRATCH8:
|
||||
case RNG_DATA:
|
||||
case SILICON_REV:
|
||||
case FREE_CNTR4:
|
||||
case FREE_CNTR4_EXT:
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: Write to read-only offset 0x%" HWADDR_PRIx "\n",
|
||||
__func__, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
s->regs[reg] = data;
|
||||
}
|
||||
|
||||
static const MemoryRegionOps aspeed_scu_ops = {
|
||||
.read = aspeed_scu_read,
|
||||
.write = aspeed_scu_write,
|
||||
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||
.valid.min_access_size = 4,
|
||||
.valid.max_access_size = 4,
|
||||
.valid.unaligned = false,
|
||||
};
|
||||
|
||||
static void aspeed_scu_reset(DeviceState *dev)
|
||||
{
|
||||
AspeedSCUState *s = ASPEED_SCU(dev);
|
||||
const uint32_t *reset;
|
||||
|
||||
switch (s->silicon_rev) {
|
||||
case AST2400_A0_SILICON_REV:
|
||||
reset = ast2400_a0_resets;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
memcpy(s->regs, reset, sizeof(s->regs));
|
||||
s->regs[SILICON_REV] = s->silicon_rev;
|
||||
s->regs[HW_STRAP1] = s->hw_strap1;
|
||||
s->regs[HW_STRAP2] = s->hw_strap2;
|
||||
}
|
||||
|
||||
static uint32_t aspeed_silicon_revs[] = { AST2400_A0_SILICON_REV, };
|
||||
|
||||
static bool is_supported_silicon_rev(uint32_t silicon_rev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(aspeed_silicon_revs); i++) {
|
||||
if (silicon_rev == aspeed_silicon_revs[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void aspeed_scu_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||
AspeedSCUState *s = ASPEED_SCU(dev);
|
||||
|
||||
if (!is_supported_silicon_rev(s->silicon_rev)) {
|
||||
error_setg(errp, "Unknown silicon revision: 0x%" PRIx32,
|
||||
s->silicon_rev);
|
||||
return;
|
||||
}
|
||||
|
||||
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_scu_ops, s,
|
||||
TYPE_ASPEED_SCU, SCU_IO_REGION_SIZE);
|
||||
|
||||
sysbus_init_mmio(sbd, &s->iomem);
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_aspeed_scu = {
|
||||
.name = "aspeed.scu",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UINT32_ARRAY(regs, AspeedSCUState, ASPEED_SCU_NR_REGS),
|
||||
VMSTATE_END_OF_LIST()
|
||||
}
|
||||
};
|
||||
|
||||
static Property aspeed_scu_properties[] = {
|
||||
DEFINE_PROP_UINT32("silicon-rev", AspeedSCUState, silicon_rev, 0),
|
||||
DEFINE_PROP_UINT32("hw-strap1", AspeedSCUState, hw_strap1, 0),
|
||||
DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap1, 0),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static void aspeed_scu_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
dc->realize = aspeed_scu_realize;
|
||||
dc->reset = aspeed_scu_reset;
|
||||
dc->desc = "ASPEED System Control Unit";
|
||||
dc->vmsd = &vmstate_aspeed_scu;
|
||||
dc->props = aspeed_scu_properties;
|
||||
}
|
||||
|
||||
static const TypeInfo aspeed_scu_info = {
|
||||
.name = TYPE_ASPEED_SCU,
|
||||
.parent = TYPE_SYS_BUS_DEVICE,
|
||||
.instance_size = sizeof(AspeedSCUState),
|
||||
.class_init = aspeed_scu_class_init,
|
||||
};
|
||||
|
||||
static void aspeed_scu_register_types(void)
|
||||
{
|
||||
type_register_static(&aspeed_scu_info);
|
||||
}
|
||||
|
||||
type_init(aspeed_scu_register_types);
|
@ -50,3 +50,6 @@ milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
|
||||
milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
|
||||
milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
|
||||
milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
|
||||
|
||||
# hw/misc/aspeed_scu.c
|
||||
aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
|
||||
|
@ -274,6 +274,11 @@ static inline unsigned tx_desc_get_last(unsigned *desc)
|
||||
return (desc[1] & DESC_1_TX_LAST) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline void tx_desc_set_last(unsigned *desc)
|
||||
{
|
||||
desc[1] |= DESC_1_TX_LAST;
|
||||
}
|
||||
|
||||
static inline unsigned tx_desc_get_length(unsigned *desc)
|
||||
{
|
||||
return desc[1] & DESC_1_LENGTH;
|
||||
@ -664,6 +669,13 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;
|
||||
bytes_to_copy = size;
|
||||
|
||||
/* Hardware allows a zero value here but warns against it. To avoid QEMU
|
||||
* indefinite loops we enforce a minimum value here
|
||||
*/
|
||||
if (rxbufsize < GEM_DMACFG_RBUFSZ_MUL) {
|
||||
rxbufsize = GEM_DMACFG_RBUFSZ_MUL;
|
||||
}
|
||||
|
||||
/* Pad to minimum length. Assume FCS field is stripped, logic
|
||||
* below will increment it to the real minimum of 64 when
|
||||
* not FCS stripping
|
||||
@ -932,6 +944,7 @@ static void gem_transmit(CadenceGEMState *s)
|
||||
|
||||
/* read next descriptor */
|
||||
if (tx_desc_get_wrap(desc)) {
|
||||
tx_desc_set_last(desc);
|
||||
packet_desc_addr = s->regs[GEM_TXQBASE];
|
||||
} else {
|
||||
packet_desc_addr += 8;
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "hw/arm/arm.h"
|
||||
#include "hw/intc/aspeed_vic.h"
|
||||
#include "hw/misc/aspeed_scu.h"
|
||||
#include "hw/timer/aspeed_timer.h"
|
||||
#include "hw/i2c/aspeed_i2c.h"
|
||||
|
||||
@ -27,6 +28,7 @@ typedef struct AST2400State {
|
||||
AspeedVICState vic;
|
||||
AspeedTimerCtrlState timerctrl;
|
||||
AspeedI2CState i2c;
|
||||
AspeedSCUState scu;
|
||||
} AST2400State;
|
||||
|
||||
#define TYPE_AST2400 "ast2400"
|
||||
|
34
include/hw/misc/aspeed_scu.h
Normal file
34
include/hw/misc/aspeed_scu.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* ASPEED System Control Unit
|
||||
*
|
||||
* Andrew Jeffery <andrew@aj.id.au>
|
||||
*
|
||||
* Copyright 2016 IBM Corp.
|
||||
*
|
||||
* This code is licensed under the GPL version 2 or later. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*/
|
||||
#ifndef ASPEED_SCU_H
|
||||
#define ASPEED_SCU_H
|
||||
|
||||
#include "hw/sysbus.h"
|
||||
|
||||
#define TYPE_ASPEED_SCU "aspeed.scu"
|
||||
#define ASPEED_SCU(obj) OBJECT_CHECK(AspeedSCUState, (obj), TYPE_ASPEED_SCU)
|
||||
|
||||
#define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
|
||||
|
||||
typedef struct AspeedSCUState {
|
||||
/*< private >*/
|
||||
SysBusDevice parent_obj;
|
||||
|
||||
/*< public >*/
|
||||
MemoryRegion iomem;
|
||||
|
||||
uint32_t regs[ASPEED_SCU_NR_REGS];
|
||||
uint32_t silicon_rev;
|
||||
uint32_t hw_strap1;
|
||||
uint32_t hw_strap2;
|
||||
} AspeedSCUState;
|
||||
|
||||
#endif /* ASPEED_SCU_H */
|
@ -251,7 +251,7 @@ check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
|
||||
gcov-files-sparc-y += hw/timer/m48t59.c
|
||||
gcov-files-sparc64-y += hw/timer/m48t59.c
|
||||
check-qtest-arm-y = tests/tmp105-test$(EXESUF)
|
||||
check-qtest-arm-y = tests/ds1338-test$(EXESUF)
|
||||
check-qtest-arm-y += tests/ds1338-test$(EXESUF)
|
||||
gcov-files-arm-y += hw/misc/tmp105.c
|
||||
check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
|
||||
gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
|
||||
|
Loading…
Reference in New Issue
Block a user