mirror of https://github.com/xemu-project/xemu.git
Merge remote-tracking branch 'pmaydell/arm-devs.next' into staging
* pmaydell/arm-devs.next: arm: Move some ARM devices into libhw ssd0323: abort() instead of exit(1) on error. hw/sd.c: make sd_wp_addr() return bool hw/sd.c: make sd_dataready() return bool hw/sd.c: convert binary variables to bool hw/sd.c: introduce wrapper for conversion address to wp group hw/sd.c: make sd_wp_addr() accept 64 bit address argument hw/sd.c: convert wp_groups in SDState to bitfield armv7m: Guard against no -kernel argument hw/armv7m_nvic: Fix incorrect default for num-irqs property
This commit is contained in:
commit
6a1f9d0c1f
|
@ -27,3 +27,21 @@ CONFIG_SMC91C111=y
|
|||
CONFIG_DS1338=y
|
||||
CONFIG_PFLASH_CFI01=y
|
||||
CONFIG_PFLASH_CFI02=y
|
||||
|
||||
CONFIG_ARM_TIMER=y
|
||||
CONFIG_PL011=y
|
||||
CONFIG_PL022=y
|
||||
CONFIG_PL031=y
|
||||
CONFIG_PL041=y
|
||||
CONFIG_PL050=y
|
||||
CONFIG_PL061=y
|
||||
CONFIG_PL080=y
|
||||
CONFIG_PL110=y
|
||||
CONFIG_PL181=y
|
||||
CONFIG_PL190=y
|
||||
CONFIG_PL310=y
|
||||
CONFIG_CADENCE=y
|
||||
CONFIG_XGMAC=y
|
||||
|
||||
CONFIG_VERSATILE_PCI=y
|
||||
CONFIG_VERSATILE_I2C=y
|
||||
|
|
|
@ -74,6 +74,26 @@ hw-obj-$(CONFIG_PUV3) += puv3_gpio.o
|
|||
hw-obj-$(CONFIG_PUV3) += puv3_pm.o
|
||||
hw-obj-$(CONFIG_PUV3) += puv3_dma.o
|
||||
|
||||
# ARM devices
|
||||
hw-obj-$(CONFIG_ARM_TIMER) += arm_timer.o
|
||||
hw-obj-$(CONFIG_PL011) += pl011.o
|
||||
hw-obj-$(CONFIG_PL022) += pl022.o
|
||||
hw-obj-$(CONFIG_PL031) += pl031.o
|
||||
hw-obj-$(CONFIG_PL041) += pl041.o lm4549.o
|
||||
hw-obj-$(CONFIG_PL050) += pl050.o
|
||||
hw-obj-$(CONFIG_PL061) += pl061.o
|
||||
hw-obj-$(CONFIG_PL080) += pl080.o
|
||||
hw-obj-$(CONFIG_PL110) += pl110.o
|
||||
hw-obj-$(CONFIG_PL181) += pl181.o
|
||||
hw-obj-$(CONFIG_PL190) += pl190.o
|
||||
hw-obj-$(CONFIG_PL310) += arm_l2x0.o
|
||||
hw-obj-$(CONFIG_VERSATILE_PCI) += versatile_pci.o
|
||||
hw-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o
|
||||
hw-obj-$(CONFIG_CADENCE) += cadence_uart.o
|
||||
hw-obj-$(CONFIG_CADENCE) += cadence_ttc.o
|
||||
hw-obj-$(CONFIG_CADENCE) += cadence_gem.o
|
||||
hw-obj-$(CONFIG_XGMAC) += xgmac.o
|
||||
|
||||
# PCI watchdog devices
|
||||
hw-obj-$(CONFIG_PCI) += wdt_i6300esb.o
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
obj-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o
|
||||
obj-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
|
||||
obj-y += versatile_pci.o
|
||||
obj-y += versatile_i2c.o
|
||||
obj-y += cadence_uart.o
|
||||
obj-y += cadence_ttc.o
|
||||
obj-y += cadence_gem.o
|
||||
obj-y = integratorcp.o versatilepb.o arm_pic.o
|
||||
obj-y += arm_boot.o
|
||||
obj-y += xilinx_zynq.o zynq_slcr.o
|
||||
obj-y += arm_gic.o arm_gic_common.o
|
||||
obj-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
|
||||
|
@ -12,12 +7,9 @@ obj-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
|
|||
obj-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
|
||||
obj-y += exynos4210_pmu.o exynos4210_mct.o exynos4210_fimd.o
|
||||
obj-y += exynos4210_rtc.o exynos4210_i2c.o
|
||||
obj-y += arm_l2x0.o
|
||||
obj-y += arm_mptimer.o a15mpcore.o
|
||||
obj-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
|
||||
obj-y += armv7m.o armv7m_nvic.o stellaris.o stellaris_enet.o
|
||||
obj-y += highbank.o
|
||||
obj-y += pl061.o
|
||||
obj-y += xgmac.o
|
||||
obj-y += pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
|
||||
obj-y += pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
|
||||
obj-y += gumstix.o
|
||||
|
@ -37,7 +29,6 @@ obj-y += strongarm.o
|
|||
obj-y += collie.o
|
||||
obj-y += imx_serial.o imx_ccm.o imx_timer.o imx_avic.o
|
||||
obj-y += kzm.o
|
||||
obj-y += pl041.o lm4549.o
|
||||
obj-$(CONFIG_FDT) += ../device_tree.o
|
||||
|
||||
obj-y := $(addprefix ../,$(obj-y))
|
||||
|
|
|
@ -227,6 +227,11 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
|
|||
big_endian = 0;
|
||||
#endif
|
||||
|
||||
if (!kernel_filename) {
|
||||
fprintf(stderr, "Guest image must be specified (using -kernel)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
image_size = load_elf(kernel_filename, NULL, NULL, &entry, &lowaddr,
|
||||
NULL, big_endian, ELF_MACHINE, 1);
|
||||
if (image_size < 0) {
|
||||
|
|
|
@ -467,7 +467,7 @@ static int armv7m_nvic_init(SysBusDevice *dev)
|
|||
s->gic.num_cpu = 1;
|
||||
/* Tell the common code we're an NVIC */
|
||||
s->gic.revision = 0xffffffff;
|
||||
s->gic.num_irq = s->num_irq;
|
||||
s->num_irq = s->gic.num_irq;
|
||||
nc->parent_init(dev);
|
||||
gic_init_irqs_and_distributor(&s->gic, s->num_irq);
|
||||
/* The NVIC and system controller register area looks like this:
|
||||
|
@ -498,14 +498,21 @@ static int armv7m_nvic_init(SysBusDevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static Property armv7m_nvic_properties[] = {
|
||||
static void armv7m_nvic_instance_init(Object *obj)
|
||||
{
|
||||
/* We have a different default value for the num-irq property
|
||||
* than our superclass. This function runs after qdev init
|
||||
* has set the defaults from the Property array and before
|
||||
* any user-specified property setting, so just modify the
|
||||
* value in the gic_state struct.
|
||||
*/
|
||||
gic_state *s = ARM_GIC_COMMON(obj);
|
||||
/* The ARM v7m may have anything from 0 to 496 external interrupt
|
||||
* IRQ lines. We default to 64. Other boards may differ and should
|
||||
* set this property appropriately.
|
||||
* set the num-irq property appropriately.
|
||||
*/
|
||||
DEFINE_PROP_UINT32("num-irq", nvic_state, num_irq, 64),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
s->num_irq = 64;
|
||||
}
|
||||
|
||||
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
|
@ -518,12 +525,12 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
|
|||
sdc->init = armv7m_nvic_init;
|
||||
dc->vmsd = &vmstate_nvic;
|
||||
dc->reset = armv7m_nvic_reset;
|
||||
dc->props = armv7m_nvic_properties;
|
||||
}
|
||||
|
||||
static TypeInfo armv7m_nvic_info = {
|
||||
.name = TYPE_NVIC,
|
||||
.parent = TYPE_ARM_GIC_COMMON,
|
||||
.instance_init = armv7m_nvic_instance_init,
|
||||
.instance_size = sizeof(nvic_state),
|
||||
.class_init = armv7m_nvic_class_init,
|
||||
.class_size = sizeof(NVICClass),
|
||||
|
|
72
hw/sd.c
72
hw/sd.c
|
@ -32,6 +32,7 @@
|
|||
#include "hw.h"
|
||||
#include "block.h"
|
||||
#include "sd.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
//#define DEBUG_SD 1
|
||||
|
||||
|
@ -80,8 +81,8 @@ struct SDState {
|
|||
uint32_t card_status;
|
||||
uint8_t sd_status[64];
|
||||
uint32_t vhs;
|
||||
int wp_switch;
|
||||
int *wp_groups;
|
||||
bool wp_switch;
|
||||
unsigned long *wp_groups;
|
||||
uint64_t size;
|
||||
int blk_len;
|
||||
uint32_t erase_start;
|
||||
|
@ -90,12 +91,12 @@ struct SDState {
|
|||
int pwd_len;
|
||||
int function_group[6];
|
||||
|
||||
int spi;
|
||||
bool spi;
|
||||
int current_cmd;
|
||||
/* True if we will handle the next command as an ACMD. Note that this does
|
||||
* *not* track the APP_CMD status bit!
|
||||
*/
|
||||
int expecting_acmd;
|
||||
bool expecting_acmd;
|
||||
int blk_written;
|
||||
uint64_t data_start;
|
||||
uint32_t data_offset;
|
||||
|
@ -105,7 +106,7 @@ struct SDState {
|
|||
BlockDriverState *bdrv;
|
||||
uint8_t *buf;
|
||||
|
||||
int enable;
|
||||
bool enable;
|
||||
};
|
||||
|
||||
static void sd_set_mode(SDState *sd)
|
||||
|
@ -387,6 +388,11 @@ static void sd_response_r7_make(SDState *sd, uint8_t *response)
|
|||
response[3] = (sd->vhs >> 0) & 0xff;
|
||||
}
|
||||
|
||||
static inline uint64_t sd_addr_to_wpnum(uint64_t addr)
|
||||
{
|
||||
return addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
|
||||
}
|
||||
|
||||
static void sd_reset(SDState *sd, BlockDriverState *bdrv)
|
||||
{
|
||||
uint64_t size;
|
||||
|
@ -399,7 +405,7 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv)
|
|||
}
|
||||
size = sect << 9;
|
||||
|
||||
sect = (size >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)) + 1;
|
||||
sect = sd_addr_to_wpnum(size) + 1;
|
||||
|
||||
sd->state = sd_idle_state;
|
||||
sd->rca = 0x0000;
|
||||
|
@ -414,15 +420,15 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv)
|
|||
|
||||
if (sd->wp_groups)
|
||||
g_free(sd->wp_groups);
|
||||
sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : 0;
|
||||
sd->wp_groups = (int *) g_malloc0(sizeof(int) * sect);
|
||||
sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : false;
|
||||
sd->wp_groups = bitmap_new(sect);
|
||||
memset(sd->function_group, 0, sizeof(int) * 6);
|
||||
sd->erase_start = 0;
|
||||
sd->erase_end = 0;
|
||||
sd->size = size;
|
||||
sd->blk_len = 0x200;
|
||||
sd->pwd_len = 0;
|
||||
sd->expecting_acmd = 0;
|
||||
sd->expecting_acmd = false;
|
||||
}
|
||||
|
||||
static void sd_cardchange(void *opaque, bool load)
|
||||
|
@ -444,14 +450,14 @@ static const BlockDevOps sd_block_ops = {
|
|||
whether card should be in SSI or MMC/SD mode. It is also up to the
|
||||
board to ensure that ssi transfers only occur when the chip select
|
||||
is asserted. */
|
||||
SDState *sd_init(BlockDriverState *bs, int is_spi)
|
||||
SDState *sd_init(BlockDriverState *bs, bool is_spi)
|
||||
{
|
||||
SDState *sd;
|
||||
|
||||
sd = (SDState *) g_malloc0(sizeof(SDState));
|
||||
sd->buf = qemu_blockalign(bs, 512);
|
||||
sd->spi = is_spi;
|
||||
sd->enable = 1;
|
||||
sd->enable = true;
|
||||
sd_reset(sd, bs);
|
||||
if (sd->bdrv) {
|
||||
bdrv_attach_dev_nofail(sd->bdrv, sd);
|
||||
|
@ -476,17 +482,17 @@ static void sd_erase(SDState *sd)
|
|||
return;
|
||||
}
|
||||
|
||||
start = sd->erase_start >>
|
||||
(HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
|
||||
end = sd->erase_end >>
|
||||
(HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
|
||||
start = sd_addr_to_wpnum(sd->erase_start);
|
||||
end = sd_addr_to_wpnum(sd->erase_end);
|
||||
sd->erase_start = 0;
|
||||
sd->erase_end = 0;
|
||||
sd->csd[14] |= 0x40;
|
||||
|
||||
for (i = start; i <= end; i ++)
|
||||
if (sd->wp_groups[i])
|
||||
for (i = start; i <= end; i++) {
|
||||
if (test_bit(i, sd->wp_groups)) {
|
||||
sd->card_status |= WP_ERASE_SKIP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
|
||||
|
@ -494,11 +500,13 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
|
|||
uint32_t i, wpnum;
|
||||
uint32_t ret = 0;
|
||||
|
||||
wpnum = addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
|
||||
wpnum = sd_addr_to_wpnum(addr);
|
||||
|
||||
for (i = 0; i < 32; i ++, wpnum ++, addr += WPGROUP_SIZE)
|
||||
if (addr < sd->size && sd->wp_groups[wpnum])
|
||||
for (i = 0; i < 32; i++, wpnum++, addr += WPGROUP_SIZE) {
|
||||
if (addr < sd->size && test_bit(wpnum, sd->wp_groups)) {
|
||||
ret |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -534,10 +542,9 @@ static void sd_function_switch(SDState *sd, uint32_t arg)
|
|||
sd->data[66] = crc & 0xff;
|
||||
}
|
||||
|
||||
static inline int sd_wp_addr(SDState *sd, uint32_t addr)
|
||||
static inline bool sd_wp_addr(SDState *sd, uint64_t addr)
|
||||
{
|
||||
return sd->wp_groups[addr >>
|
||||
(HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)];
|
||||
return test_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
|
||||
}
|
||||
|
||||
static void sd_lock_command(SDState *sd)
|
||||
|
@ -560,8 +567,7 @@ static void sd_lock_command(SDState *sd)
|
|||
sd->card_status |= LOCK_UNLOCK_FAILED;
|
||||
return;
|
||||
}
|
||||
memset(sd->wp_groups, 0, sizeof(int) * (sd->size >>
|
||||
(HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)));
|
||||
bitmap_zero(sd->wp_groups, sd_addr_to_wpnum(sd->size) + 1);
|
||||
sd->csd[14] &= ~0x10;
|
||||
sd->card_status &= ~CARD_IS_LOCKED;
|
||||
sd->pwd_len = 0;
|
||||
|
@ -1007,8 +1013,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
|
|||
}
|
||||
|
||||
sd->state = sd_programming_state;
|
||||
sd->wp_groups[addr >> (HWBLOCK_SHIFT +
|
||||
SECTOR_SHIFT + WPGROUP_SHIFT)] = 1;
|
||||
set_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
|
||||
/* Bzzzzzzztt .... Operation complete. */
|
||||
sd->state = sd_transfer_state;
|
||||
return sd_r1b;
|
||||
|
@ -1027,8 +1032,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
|
|||
}
|
||||
|
||||
sd->state = sd_programming_state;
|
||||
sd->wp_groups[addr >> (HWBLOCK_SHIFT +
|
||||
SECTOR_SHIFT + WPGROUP_SHIFT)] = 0;
|
||||
clear_bit(sd_addr_to_wpnum(addr), sd->wp_groups);
|
||||
/* Bzzzzzzztt .... Operation complete. */
|
||||
sd->state = sd_transfer_state;
|
||||
return sd_r1b;
|
||||
|
@ -1125,7 +1129,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
|
|||
if (sd->rca != rca)
|
||||
return sd_r0;
|
||||
|
||||
sd->expecting_acmd = 1;
|
||||
sd->expecting_acmd = true;
|
||||
sd->card_status |= APP_CMD;
|
||||
return sd_r1;
|
||||
|
||||
|
@ -1307,7 +1311,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
|
|||
if (sd->card_status & CARD_IS_LOCKED) {
|
||||
if (!cmd_valid_while_locked(sd, req)) {
|
||||
sd->card_status |= ILLEGAL_COMMAND;
|
||||
sd->expecting_acmd = 0;
|
||||
sd->expecting_acmd = false;
|
||||
fprintf(stderr, "SD: Card is locked\n");
|
||||
rtype = sd_illegal;
|
||||
goto send_response;
|
||||
|
@ -1318,7 +1322,7 @@ int sd_do_command(SDState *sd, SDRequest *req,
|
|||
sd_set_mode(sd);
|
||||
|
||||
if (sd->expecting_acmd) {
|
||||
sd->expecting_acmd = 0;
|
||||
sd->expecting_acmd = false;
|
||||
rtype = sd_app_command(sd, *req);
|
||||
} else {
|
||||
rtype = sd_normal_command(sd, *req);
|
||||
|
@ -1699,12 +1703,12 @@ uint8_t sd_read_data(SDState *sd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int sd_data_ready(SDState *sd)
|
||||
bool sd_data_ready(SDState *sd)
|
||||
{
|
||||
return sd->state == sd_sendingdata_state;
|
||||
}
|
||||
|
||||
void sd_enable(SDState *sd, int enable)
|
||||
void sd_enable(SDState *sd, bool enable)
|
||||
{
|
||||
sd->enable = enable;
|
||||
}
|
||||
|
|
6
hw/sd.h
6
hw/sd.h
|
@ -67,13 +67,13 @@ typedef struct {
|
|||
|
||||
typedef struct SDState SDState;
|
||||
|
||||
SDState *sd_init(BlockDriverState *bs, int is_spi);
|
||||
SDState *sd_init(BlockDriverState *bs, bool is_spi);
|
||||
int sd_do_command(SDState *sd, SDRequest *req,
|
||||
uint8_t *response);
|
||||
void sd_write_data(SDState *sd, uint8_t value);
|
||||
uint8_t sd_read_data(SDState *sd);
|
||||
void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
|
||||
int sd_data_ready(SDState *sd);
|
||||
void sd_enable(SDState *sd, int enable);
|
||||
bool sd_data_ready(SDState *sd);
|
||||
void sd_enable(SDState *sd, bool enable);
|
||||
|
||||
#endif /* __hw_sd_h */
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#define DPRINTF(fmt, ...) \
|
||||
do { printf("ssd0323: " fmt , ## __VA_ARGS__); } while (0)
|
||||
#define BADF(fmt, ...) \
|
||||
do { fprintf(stderr, "ssd0323: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
|
||||
do { \
|
||||
fprintf(stderr, "ssd0323: error: " fmt , ## __VA_ARGS__); abort(); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...) do {} while(0)
|
||||
#define BADF(fmt, ...) \
|
||||
|
|
Loading…
Reference in New Issue