mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20160704' into staging
target-arm queue: * fix semihosting SYS_HEAPINFO call for A64 guests * fix crash if guest tries to write to ROM on imx boards * armv7m_nvic: fix crash for debugger reads from some registers * virt: mark PCIe host controller as dma-coherent in the DT * add data-driven register API * Xilinx Zynq: add devcfg device model * m25p80: fix various bugs * ast2400: add SMC controllers and SPI flash slaves # gpg: Signature made Mon 04 Jul 2016 13:17:34 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-20160704: (23 commits) ast2400: create SPI flash slaves ast2400: add SPI flash slaves ast2400: add SMC controllers (FMC and SPI) m25p80: qdev-ify drive property m25p80: change cur_addr to 32 bit integer m25p80: avoid out of bounds accesses m25p80: do not put iovec on the stack ssi: change ssi_slave_init to be a realize ops xilinx_zynq: Connect devcfg to the Zynq machine model dma: Add Xilinx Zynq devcfg device model register: Add block initialise helper register: QOMify register: Define REG and FIELD macros register: Add Memory API glue register: Add Register API bitops: Add MAKE_64BIT_MASK macro hw/arm/virt: mark the PCIe host controller as DMA coherent in the DT armv7m_nvic: Use qemu_get_cpu(0) instead of current_cpu memory: Assert that memory_region_init_rom_device() ops aren't NULL imx: Use memory_region_init_rom() for ROMs ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -66,6 +66,7 @@ CONFIG_PXA2XX=y
|
||||
CONFIG_BITBANG_I2C=y
|
||||
CONFIG_FRAMEBUFFER=y
|
||||
CONFIG_XILINX_SPIPS=y
|
||||
CONFIG_ZYNQ_DEVCFG=y
|
||||
|
||||
CONFIG_ARM11SCU=y
|
||||
CONFIG_A9SCU=y
|
||||
|
||||
+7
-2
@@ -41,8 +41,13 @@ MemoryRegion):
|
||||
MemoryRegionOps structure describing the callbacks.
|
||||
|
||||
- ROM: a ROM memory region works like RAM for reads (directly accessing
|
||||
a region of host memory), but like MMIO for writes (invoking a callback).
|
||||
You initialize these with memory_region_init_rom_device().
|
||||
a region of host memory), and forbids writes. You initialize these with
|
||||
memory_region_init_rom().
|
||||
|
||||
- ROM device: a ROM device memory region works like RAM for reads
|
||||
(directly accessing a region of host memory), but like MMIO for
|
||||
writes (invoking a callback). You initialize these with
|
||||
memory_region_init_rom_device().
|
||||
|
||||
- IOMMU region: an IOMMU region translates addresses of accesses made to it
|
||||
and forwards them to some other target memory region. As the name suggests,
|
||||
|
||||
+39
-1
@@ -23,11 +23,17 @@
|
||||
#define AST2400_UART_5_BASE 0x00184000
|
||||
#define AST2400_IOMEM_SIZE 0x00200000
|
||||
#define AST2400_IOMEM_BASE 0x1E600000
|
||||
#define AST2400_SMC_BASE AST2400_IOMEM_BASE /* Legacy SMC */
|
||||
#define AST2400_FMC_BASE 0X1E620000
|
||||
#define AST2400_SPI_BASE 0X1E630000
|
||||
#define AST2400_VIC_BASE 0x1E6C0000
|
||||
#define AST2400_SCU_BASE 0x1E6E2000
|
||||
#define AST2400_TIMER_BASE 0x1E782000
|
||||
#define AST2400_I2C_BASE 0x1E78A000
|
||||
|
||||
#define AST2400_FMC_FLASH_BASE 0x20000000
|
||||
#define AST2400_SPI_FLASH_BASE 0x30000000
|
||||
|
||||
#define AST2400_A0_SILICON_REV 0x02000303
|
||||
|
||||
static const int uart_irqs[] = { 9, 32, 33, 34, 10 };
|
||||
@@ -85,13 +91,21 @@ static void ast2400_init(Object *obj)
|
||||
"hw-strap1", &error_abort);
|
||||
object_property_add_alias(obj, "hw-strap2", OBJECT(&s->scu),
|
||||
"hw-strap2", &error_abort);
|
||||
|
||||
object_initialize(&s->smc, sizeof(s->smc), "aspeed.smc.fmc");
|
||||
object_property_add_child(obj, "smc", OBJECT(&s->smc), NULL);
|
||||
qdev_set_parent_bus(DEVICE(&s->smc), sysbus_get_default());
|
||||
|
||||
object_initialize(&s->spi, sizeof(s->spi), "aspeed.smc.spi");
|
||||
object_property_add_child(obj, "spi", OBJECT(&s->spi), NULL);
|
||||
qdev_set_parent_bus(DEVICE(&s->spi), sysbus_get_default());
|
||||
}
|
||||
|
||||
static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
int i;
|
||||
AST2400State *s = AST2400(dev);
|
||||
Error *err = NULL;
|
||||
Error *err = NULL, *local_err = NULL;
|
||||
|
||||
/* IO space */
|
||||
memory_region_init_io(&s->iomem, NULL, &ast2400_io_ops, NULL,
|
||||
@@ -147,6 +161,30 @@ static void ast2400_realize(DeviceState *dev, Error **errp)
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c), 0, AST2400_I2C_BASE);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c), 0,
|
||||
qdev_get_gpio_in(DEVICE(&s->vic), 12));
|
||||
|
||||
/* SMC */
|
||||
object_property_set_int(OBJECT(&s->smc), 1, "num-cs", &err);
|
||||
object_property_set_bool(OBJECT(&s->smc), true, "realized", &local_err);
|
||||
error_propagate(&err, local_err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 0, AST2400_FMC_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->smc), 1, AST2400_FMC_FLASH_BASE);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->smc), 0,
|
||||
qdev_get_gpio_in(DEVICE(&s->vic), 19));
|
||||
|
||||
/* SPI */
|
||||
object_property_set_int(OBJECT(&s->spi), 1, "num-cs", &err);
|
||||
object_property_set_bool(OBJECT(&s->spi), true, "realized", &local_err);
|
||||
error_propagate(&err, local_err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 0, AST2400_SPI_BASE);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi), 1, AST2400_SPI_FLASH_BASE);
|
||||
}
|
||||
|
||||
static void ast2400_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
+4
-4
@@ -249,16 +249,16 @@ static void fsl_imx25_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/* initialize 2 x 16 KB ROM */
|
||||
memory_region_init_rom_device(&s->rom[0], NULL, NULL, NULL,
|
||||
"imx25.rom0", FSL_IMX25_ROM0_SIZE, &err);
|
||||
memory_region_init_rom(&s->rom[0], NULL,
|
||||
"imx25.rom0", FSL_IMX25_ROM0_SIZE, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
}
|
||||
memory_region_add_subregion(get_system_memory(), FSL_IMX25_ROM0_ADDR,
|
||||
&s->rom[0]);
|
||||
memory_region_init_rom_device(&s->rom[1], NULL, NULL, NULL,
|
||||
"imx25.rom1", FSL_IMX25_ROM1_SIZE, &err);
|
||||
memory_region_init_rom(&s->rom[1], NULL,
|
||||
"imx25.rom1", FSL_IMX25_ROM1_SIZE, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
|
||||
+4
-5
@@ -219,9 +219,8 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
/* On a real system, the first 16k is a `secure boot rom' */
|
||||
memory_region_init_rom_device(&s->secure_rom, NULL, NULL, NULL,
|
||||
"imx31.secure_rom",
|
||||
FSL_IMX31_SECURE_ROM_SIZE, &err);
|
||||
memory_region_init_rom(&s->secure_rom, NULL, "imx31.secure_rom",
|
||||
FSL_IMX31_SECURE_ROM_SIZE, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
@@ -230,8 +229,8 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp)
|
||||
&s->secure_rom);
|
||||
|
||||
/* There is also a 16k ROM */
|
||||
memory_region_init_rom_device(&s->rom, NULL, NULL, NULL, "imx31.rom",
|
||||
FSL_IMX31_ROM_SIZE, &err);
|
||||
memory_region_init_rom(&s->rom, NULL, "imx31.rom",
|
||||
FSL_IMX31_ROM_SIZE, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
|
||||
+4
-4
@@ -399,8 +399,8 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
|
||||
FSL_IMX6_ENET_MAC_1588_IRQ));
|
||||
|
||||
/* ROM memory */
|
||||
memory_region_init_rom_device(&s->rom, NULL, NULL, NULL, "imx6.rom",
|
||||
FSL_IMX6_ROM_SIZE, &err);
|
||||
memory_region_init_rom(&s->rom, NULL, "imx6.rom",
|
||||
FSL_IMX6_ROM_SIZE, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
@@ -409,8 +409,8 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
|
||||
&s->rom);
|
||||
|
||||
/* CAAM memory */
|
||||
memory_region_init_rom_device(&s->caam, NULL, NULL, NULL, "imx6.caam",
|
||||
FSL_IMX6_CAAM_MEM_SIZE, &err);
|
||||
memory_region_init_rom(&s->caam, NULL, "imx6.caam",
|
||||
FSL_IMX6_CAAM_MEM_SIZE, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "hw/arm/ast2400.h"
|
||||
#include "hw/boards.h"
|
||||
#include "qemu/log.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
|
||||
static struct arm_boot_info palmetto_bmc_binfo = {
|
||||
.loader_start = AST2400_SDRAM_BASE,
|
||||
@@ -30,6 +32,32 @@ typedef struct PalmettoBMCState {
|
||||
MemoryRegion ram;
|
||||
} PalmettoBMCState;
|
||||
|
||||
static void palmetto_bmc_init_flashes(AspeedSMCState *s, const char *flashtype,
|
||||
Error **errp)
|
||||
{
|
||||
int i ;
|
||||
|
||||
for (i = 0; i < s->num_cs; ++i) {
|
||||
AspeedSMCFlash *fl = &s->flashes[i];
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
qemu_irq cs_line;
|
||||
|
||||
/*
|
||||
* FIXME: check that we are not using a flash module exceeding
|
||||
* the controller segment size
|
||||
*/
|
||||
fl->flash = ssi_create_slave_no_init(s->spi, flashtype);
|
||||
if (dinfo) {
|
||||
qdev_prop_set_drive(fl->flash, "drive", blk_by_legacy_dinfo(dinfo),
|
||||
errp);
|
||||
}
|
||||
qdev_init_nofail(fl->flash);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(fl->flash, SSI_GPIO_CS, 0);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(s), i + 1, cs_line);
|
||||
}
|
||||
}
|
||||
|
||||
static void palmetto_bmc_init(MachineState *machine)
|
||||
{
|
||||
PalmettoBMCState *bmc;
|
||||
@@ -49,6 +77,9 @@ static void palmetto_bmc_init(MachineState *machine)
|
||||
object_property_set_bool(OBJECT(&bmc->soc), true, "realized",
|
||||
&error_abort);
|
||||
|
||||
palmetto_bmc_init_flashes(&bmc->soc.smc, "n25q256a", &error_abort);
|
||||
palmetto_bmc_init_flashes(&bmc->soc.spi, "mx25l25635e", &error_abort);
|
||||
|
||||
palmetto_bmc_binfo.kernel_filename = machine->kernel_filename;
|
||||
palmetto_bmc_binfo.initrd_filename = machine->initrd_filename;
|
||||
palmetto_bmc_binfo.kernel_cmdline = machine->kernel_cmdline;
|
||||
|
||||
+11
-5
@@ -86,13 +86,19 @@ static void sabrelite_init(MachineState *machine)
|
||||
spi_bus = (SSIBus *)qdev_get_child_bus(DEVICE(spi_dev), "spi");
|
||||
if (spi_bus) {
|
||||
DeviceState *flash_dev;
|
||||
qemu_irq cs_line;
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
|
||||
flash_dev = ssi_create_slave(spi_bus, "sst25vf016b");
|
||||
if (flash_dev) {
|
||||
qemu_irq cs_line = qdev_get_gpio_in_named(flash_dev,
|
||||
SSI_GPIO_CS, 0);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(spi_dev), 1, cs_line);
|
||||
flash_dev = ssi_create_slave_no_init(spi_bus, "sst25vf016b");
|
||||
if (dinfo) {
|
||||
qdev_prop_set_drive(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo),
|
||||
&error_fatal);
|
||||
}
|
||||
qdev_init_nofail(flash_dev);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(spi_dev), 1, cs_line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-8
@@ -598,15 +598,13 @@ static uint32_t spitz_lcdtg_transfer(SSISlave *dev, uint32_t value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spitz_lcdtg_init(SSISlave *dev)
|
||||
static void spitz_lcdtg_realize(SSISlave *dev, Error **errp)
|
||||
{
|
||||
SpitzLCDTG *s = FROM_SSI_SLAVE(SpitzLCDTG, dev);
|
||||
|
||||
spitz_lcdtg = s;
|
||||
s->bl_power = 0;
|
||||
s->bl_intensity = 0x20;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SSP devices */
|
||||
@@ -666,7 +664,7 @@ static void spitz_adc_temp_on(void *opaque, int line, int level)
|
||||
max111x_set_input(max1111, MAX1111_BATT_TEMP, 0);
|
||||
}
|
||||
|
||||
static int corgi_ssp_init(SSISlave *d)
|
||||
static void corgi_ssp_realize(SSISlave *d, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(d);
|
||||
CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, d);
|
||||
@@ -675,8 +673,6 @@ static int corgi_ssp_init(SSISlave *d)
|
||||
s->bus[0] = ssi_create_bus(dev, "ssi0");
|
||||
s->bus[1] = ssi_create_bus(dev, "ssi1");
|
||||
s->bus[2] = ssi_create_bus(dev, "ssi2");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spitz_ssp_attach(PXA2xxState *cpu)
|
||||
@@ -1121,7 +1117,7 @@ static void corgi_ssp_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = corgi_ssp_init;
|
||||
k->realize = corgi_ssp_realize;
|
||||
k->transfer = corgi_ssp_transfer;
|
||||
dc->vmsd = &vmstate_corgi_ssp_regs;
|
||||
}
|
||||
@@ -1150,7 +1146,7 @@ static void spitz_lcdtg_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = spitz_lcdtg_init;
|
||||
k->realize = spitz_lcdtg_realize;
|
||||
k->transfer = spitz_lcdtg_transfer;
|
||||
dc->vmsd = &vmstate_spitz_lcdtg_regs;
|
||||
}
|
||||
|
||||
+2
-3
@@ -127,10 +127,9 @@ static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tosa_ssp_init(SSISlave *dev)
|
||||
static void tosa_ssp_realize(SSISlave *dev, Error **errp)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TYPE_TOSA_DAC "tosa_dac"
|
||||
@@ -283,7 +282,7 @@ static void tosa_ssp_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = tosa_ssp_init;
|
||||
k->realize = tosa_ssp_realize;
|
||||
k->transfer = tosa_ssp_tansfer;
|
||||
}
|
||||
|
||||
|
||||
@@ -1021,6 +1021,7 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
|
||||
qemu_fdt_setprop_cell(vbi->fdt, nodename, "#size-cells", 2);
|
||||
qemu_fdt_setprop_cells(vbi->fdt, nodename, "bus-range", 0,
|
||||
nr_pcie_buses - 1);
|
||||
qemu_fdt_setprop(vbi->fdt, nodename, "dma-coherent", NULL, 0);
|
||||
|
||||
if (vbi->v2m_phandle) {
|
||||
qemu_fdt_setprop_cells(vbi->fdt, nodename, "msi-parent",
|
||||
|
||||
+13
-1
@@ -138,7 +138,13 @@ static inline void zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
|
||||
spi = (SSIBus *)qdev_get_child_bus(dev, bus_name);
|
||||
|
||||
for (j = 0; j < num_ss; ++j) {
|
||||
flash_dev = ssi_create_slave(spi, "n25q128");
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
flash_dev = ssi_create_slave_no_init(spi, "n25q128");
|
||||
if (dinfo) {
|
||||
qdev_prop_set_drive(flash_dev, "drive",
|
||||
blk_by_legacy_dinfo(dinfo), &error_fatal);
|
||||
}
|
||||
qdev_init_nofail(flash_dev);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
sysbus_connect_irq(busdev, i * num_ss + j + 1, cs_line);
|
||||
@@ -294,6 +300,12 @@ static void zynq_init(MachineState *machine)
|
||||
sysbus_connect_irq(busdev, n + 1, pic[dma_irqs[n] - IRQ_OFFSET]);
|
||||
}
|
||||
|
||||
dev = qdev_create(NULL, "xlnx.ps7-dev-cfg");
|
||||
qdev_init_nofail(dev);
|
||||
busdev = SYS_BUS_DEVICE(dev);
|
||||
sysbus_connect_irq(busdev, 0, pic[40 - IRQ_OFFSET]);
|
||||
sysbus_mmio_map(busdev, 0, 0xF8007000);
|
||||
|
||||
zynq_binfo.ram_size = ram_size;
|
||||
zynq_binfo.kernel_filename = kernel_filename;
|
||||
zynq_binfo.kernel_cmdline = kernel_cmdline;
|
||||
|
||||
+8
-1
@@ -88,12 +88,19 @@ static void xlnx_ep108_init(MachineState *machine)
|
||||
SSIBus *spi_bus;
|
||||
DeviceState *flash_dev;
|
||||
qemu_irq cs_line;
|
||||
DriveInfo *dinfo = drive_get_next(IF_MTD);
|
||||
gchar *bus_name = g_strdup_printf("spi%d", i);
|
||||
|
||||
spi_bus = (SSIBus *)qdev_get_child_bus(DEVICE(&s->soc), bus_name);
|
||||
g_free(bus_name);
|
||||
|
||||
flash_dev = ssi_create_slave(spi_bus, "sst25wf080");
|
||||
flash_dev = ssi_create_slave_no_init(spi_bus, "sst25wf080");
|
||||
if (dinfo) {
|
||||
qdev_prop_set_drive(flash_dev, "drive", blk_by_legacy_dinfo(dinfo),
|
||||
&error_fatal);
|
||||
}
|
||||
qdev_init_nofail(flash_dev);
|
||||
|
||||
cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
|
||||
|
||||
sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi[i]), 1, cs_line);
|
||||
|
||||
+2
-4
@@ -151,14 +151,12 @@ static void z2_lcd_cs(void *opaque, int line, int level)
|
||||
z2_lcd->selected = !level;
|
||||
}
|
||||
|
||||
static int zipit_lcd_init(SSISlave *dev)
|
||||
static void zipit_lcd_realize(SSISlave *dev, Error **errp)
|
||||
{
|
||||
ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev);
|
||||
z->selected = 0;
|
||||
z->enabled = 0;
|
||||
z->pos = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static VMStateDescription vmstate_zipit_lcd_state = {
|
||||
@@ -181,7 +179,7 @@ static void zipit_lcd_class_init(ObjectClass *klass, void *data)
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = zipit_lcd_init;
|
||||
k->realize = zipit_lcd_realize;
|
||||
k->transfer = zipit_lcd_transfer;
|
||||
dc->vmsd = &vmstate_zipit_lcd_state;
|
||||
}
|
||||
|
||||
+36
-40
@@ -28,6 +28,7 @@
|
||||
#include "hw/ssi/ssi.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qapi/error.h"
|
||||
|
||||
#ifndef M25P80_ERR_DEBUG
|
||||
#define M25P80_ERR_DEBUG 0
|
||||
@@ -389,7 +390,7 @@ typedef struct Flash {
|
||||
uint32_t pos;
|
||||
uint8_t needed_bytes;
|
||||
uint8_t cmd_in_progress;
|
||||
uint64_t cur_addr;
|
||||
uint32_t cur_addr;
|
||||
uint32_t nonvolatile_cfg;
|
||||
/* Configuration register for Macronix */
|
||||
uint32_t volatile_cfg;
|
||||
@@ -446,6 +447,11 @@ static inline Manufacturer get_man(Flash *s)
|
||||
|
||||
static void blk_sync_complete(void *opaque, int ret)
|
||||
{
|
||||
QEMUIOVector *iov = opaque;
|
||||
|
||||
qemu_iovec_destroy(iov);
|
||||
g_free(iov);
|
||||
|
||||
/* do nothing. Masters do not directly interact with the backing store,
|
||||
* only the working copy so no mutexing required.
|
||||
*/
|
||||
@@ -453,31 +459,31 @@ static void blk_sync_complete(void *opaque, int ret)
|
||||
|
||||
static void flash_sync_page(Flash *s, int page)
|
||||
{
|
||||
QEMUIOVector iov;
|
||||
QEMUIOVector *iov = g_new(QEMUIOVector, 1);
|
||||
|
||||
if (!s->blk || blk_is_read_only(s->blk)) {
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_iovec_init(&iov, 1);
|
||||
qemu_iovec_add(&iov, s->storage + page * s->pi->page_size,
|
||||
qemu_iovec_init(iov, 1);
|
||||
qemu_iovec_add(iov, s->storage + page * s->pi->page_size,
|
||||
s->pi->page_size);
|
||||
blk_aio_pwritev(s->blk, page * s->pi->page_size, &iov, 0,
|
||||
blk_sync_complete, NULL);
|
||||
blk_aio_pwritev(s->blk, page * s->pi->page_size, iov, 0,
|
||||
blk_sync_complete, iov);
|
||||
}
|
||||
|
||||
static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)
|
||||
{
|
||||
QEMUIOVector iov;
|
||||
QEMUIOVector *iov = g_new(QEMUIOVector, 1);
|
||||
|
||||
if (!s->blk || blk_is_read_only(s->blk)) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!(len % BDRV_SECTOR_SIZE));
|
||||
qemu_iovec_init(&iov, 1);
|
||||
qemu_iovec_add(&iov, s->storage + off, len);
|
||||
blk_aio_pwritev(s->blk, off, &iov, 0, blk_sync_complete, NULL);
|
||||
qemu_iovec_init(iov, 1);
|
||||
qemu_iovec_add(iov, s->storage + off, len);
|
||||
blk_aio_pwritev(s->blk, off, iov, 0, blk_sync_complete, iov);
|
||||
}
|
||||
|
||||
static void flash_erase(Flash *s, int offset, FlashCMD cmd)
|
||||
@@ -530,9 +536,9 @@ static inline void flash_sync_dirty(Flash *s, int64_t newpage)
|
||||
}
|
||||
|
||||
static inline
|
||||
void flash_write8(Flash *s, uint64_t addr, uint8_t data)
|
||||
void flash_write8(Flash *s, uint32_t addr, uint8_t data)
|
||||
{
|
||||
int64_t page = addr / s->pi->page_size;
|
||||
uint32_t page = addr / s->pi->page_size;
|
||||
uint8_t prev = s->storage[s->cur_addr];
|
||||
|
||||
if (!s->write_enable) {
|
||||
@@ -540,7 +546,7 @@ void flash_write8(Flash *s, uint64_t addr, uint8_t data)
|
||||
}
|
||||
|
||||
if ((prev ^ data) & data) {
|
||||
DB_PRINT_L(1, "programming zero to one! addr=%" PRIx64 " %" PRIx8
|
||||
DB_PRINT_L(1, "programming zero to one! addr=%" PRIx32 " %" PRIx8
|
||||
" -> %" PRIx8 "\n", addr, prev, data);
|
||||
}
|
||||
|
||||
@@ -581,18 +587,16 @@ static inline int get_addr_length(Flash *s)
|
||||
|
||||
static void complete_collecting_data(Flash *s)
|
||||
{
|
||||
int i;
|
||||
int i, n;
|
||||
|
||||
s->cur_addr = 0;
|
||||
|
||||
for (i = 0; i < get_addr_length(s); ++i) {
|
||||
n = get_addr_length(s);
|
||||
s->cur_addr = (n == 3 ? s->ear : 0);
|
||||
for (i = 0; i < n; ++i) {
|
||||
s->cur_addr <<= 8;
|
||||
s->cur_addr |= s->data[i];
|
||||
}
|
||||
|
||||
if (get_addr_length(s) == 3) {
|
||||
s->cur_addr += s->ear * MAX_3BYTES_SIZE;
|
||||
}
|
||||
s->cur_addr &= s->size - 1;
|
||||
|
||||
s->state = STATE_IDLE;
|
||||
|
||||
@@ -1091,17 +1095,17 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
|
||||
switch (s->state) {
|
||||
|
||||
case STATE_PAGE_PROGRAM:
|
||||
DB_PRINT_L(1, "page program cur_addr=%#" PRIx64 " data=%" PRIx8 "\n",
|
||||
DB_PRINT_L(1, "page program cur_addr=%#" PRIx32 " data=%" PRIx8 "\n",
|
||||
s->cur_addr, (uint8_t)tx);
|
||||
flash_write8(s, s->cur_addr, (uint8_t)tx);
|
||||
s->cur_addr++;
|
||||
s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
|
||||
break;
|
||||
|
||||
case STATE_READ:
|
||||
r = s->storage[s->cur_addr];
|
||||
DB_PRINT_L(1, "READ 0x%" PRIx64 "=%" PRIx8 "\n", s->cur_addr,
|
||||
DB_PRINT_L(1, "READ 0x%" PRIx32 "=%" PRIx8 "\n", s->cur_addr,
|
||||
(uint8_t)r);
|
||||
s->cur_addr = (s->cur_addr + 1) % s->size;
|
||||
s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
|
||||
break;
|
||||
|
||||
case STATE_COLLECTING_DATA:
|
||||
@@ -1132,9 +1136,8 @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int m25p80_init(SSISlave *ss)
|
||||
static void m25p80_realize(SSISlave *ss, Error **errp)
|
||||
{
|
||||
DriveInfo *dinfo;
|
||||
Flash *s = M25P80(ss);
|
||||
M25P80Class *mc = M25P80_GET_CLASS(s);
|
||||
|
||||
@@ -1143,28 +1146,19 @@ static int m25p80_init(SSISlave *ss)
|
||||
s->size = s->pi->sector_size * s->pi->n_sectors;
|
||||
s->dirty_page = -1;
|
||||
|
||||
/* FIXME use a qdev drive property instead of drive_get_next() */
|
||||
dinfo = drive_get_next(IF_MTD);
|
||||
|
||||
if (dinfo) {
|
||||
if (s->blk) {
|
||||
DB_PRINT_L(0, "Binding to IF_MTD drive\n");
|
||||
s->blk = blk_by_legacy_dinfo(dinfo);
|
||||
blk_attach_dev_nofail(s->blk, s);
|
||||
|
||||
s->storage = blk_blockalign(s->blk, s->size);
|
||||
|
||||
/* FIXME: Move to late init */
|
||||
if (blk_pread(s->blk, 0, s->storage, s->size) != s->size) {
|
||||
fprintf(stderr, "Failed to initialize SPI flash!\n");
|
||||
return 1;
|
||||
error_setg(errp, "failed to read the initial flash content");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
DB_PRINT_L(0, "No BDRV - binding to RAM\n");
|
||||
s->storage = blk_blockalign(NULL, s->size);
|
||||
memset(s->storage, 0xFF, s->size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void m25p80_reset(DeviceState *d)
|
||||
@@ -1186,6 +1180,7 @@ static Property m25p80_properties[] = {
|
||||
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_DRIVE("drive", Flash, blk),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
@@ -1201,7 +1196,8 @@ static const VMStateDescription vmstate_m25p80 = {
|
||||
VMSTATE_UINT32(pos, Flash),
|
||||
VMSTATE_UINT8(needed_bytes, Flash),
|
||||
VMSTATE_UINT8(cmd_in_progress, Flash),
|
||||
VMSTATE_UINT64(cur_addr, Flash),
|
||||
VMSTATE_UNUSED(4),
|
||||
VMSTATE_UINT32(cur_addr, Flash),
|
||||
VMSTATE_BOOL(write_enable, Flash),
|
||||
VMSTATE_BOOL_V(reset_enable, Flash, 2),
|
||||
VMSTATE_UINT8_V(ear, Flash, 2),
|
||||
@@ -1224,7 +1220,7 @@ static void m25p80_class_init(ObjectClass *klass, void *data)
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
M25P80Class *mc = M25P80_CLASS(klass);
|
||||
|
||||
k->init = m25p80_init;
|
||||
k->realize = m25p80_realize;
|
||||
k->transfer = m25p80_transfer8;
|
||||
k->set_cs = m25p80_cs;
|
||||
k->cs_polarity = SSI_CS_LOW;
|
||||
|
||||
@@ -15,4 +15,5 @@ common-obj-$(CONFIG_SOFTMMU) += machine.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += null-machine.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += loader.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
|
||||
common-obj-$(CONFIG_SOFTMMU) += register.o
|
||||
common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Register Definition API
|
||||
*
|
||||
* Copyright (c) 2016 Xilinx Inc.
|
||||
* Copyright (c) 2013 Peter Crosthwaite <peter.crosthwaite@xilinx.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/register.h"
|
||||
#include "hw/qdev.h"
|
||||
#include "qemu/log.h"
|
||||
|
||||
static inline void register_write_val(RegisterInfo *reg, uint64_t val)
|
||||
{
|
||||
g_assert(reg->data);
|
||||
|
||||
switch (reg->data_size) {
|
||||
case 1:
|
||||
*(uint8_t *)reg->data = val;
|
||||
break;
|
||||
case 2:
|
||||
*(uint16_t *)reg->data = val;
|
||||
break;
|
||||
case 4:
|
||||
*(uint32_t *)reg->data = val;
|
||||
break;
|
||||
case 8:
|
||||
*(uint64_t *)reg->data = val;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t register_read_val(RegisterInfo *reg)
|
||||
{
|
||||
switch (reg->data_size) {
|
||||
case 1:
|
||||
return *(uint8_t *)reg->data;
|
||||
case 2:
|
||||
return *(uint16_t *)reg->data;
|
||||
case 4:
|
||||
return *(uint32_t *)reg->data;
|
||||
case 8:
|
||||
return *(uint64_t *)reg->data;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
return 0; /* unreachable */
|
||||
}
|
||||
|
||||
void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
|
||||
const char *prefix, bool debug)
|
||||
{
|
||||
uint64_t old_val, new_val, test, no_w_mask;
|
||||
const RegisterAccessInfo *ac;
|
||||
|
||||
assert(reg);
|
||||
|
||||
ac = reg->access;
|
||||
|
||||
if (!ac || !ac->name) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: write to undefined device state "
|
||||
"(written value: %#" PRIx64 ")\n", prefix, val);
|
||||
return;
|
||||
}
|
||||
|
||||
old_val = reg->data ? register_read_val(reg) : ac->reset;
|
||||
|
||||
test = (old_val ^ val) & ac->rsvd;
|
||||
if (test) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: change of value in reserved bit"
|
||||
"fields: %#" PRIx64 ")\n", prefix, test);
|
||||
}
|
||||
|
||||
test = val & ac->unimp;
|
||||
if (test) {
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"%s:%s writing %#" PRIx64 " to unimplemented bits:" \
|
||||
" %#" PRIx64 "",
|
||||
prefix, reg->access->name, val, ac->unimp);
|
||||
}
|
||||
|
||||
/* Create the no write mask based on the read only, write to clear and
|
||||
* reserved bit masks.
|
||||
*/
|
||||
no_w_mask = ac->ro | ac->w1c | ac->rsvd | ~we;
|
||||
new_val = (val & ~no_w_mask) | (old_val & no_w_mask);
|
||||
new_val &= ~(val & ac->w1c);
|
||||
|
||||
if (ac->pre_write) {
|
||||
new_val = ac->pre_write(reg, new_val);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
qemu_log("%s:%s: write of value %#" PRIx64 "\n", prefix, ac->name,
|
||||
new_val);
|
||||
}
|
||||
|
||||
register_write_val(reg, new_val);
|
||||
|
||||
if (ac->post_write) {
|
||||
ac->post_write(reg, new_val);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
|
||||
bool debug)
|
||||
{
|
||||
uint64_t ret;
|
||||
const RegisterAccessInfo *ac;
|
||||
|
||||
assert(reg);
|
||||
|
||||
ac = reg->access;
|
||||
if (!ac || !ac->name) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: read from undefined device state\n",
|
||||
prefix);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = reg->data ? register_read_val(reg) : ac->reset;
|
||||
|
||||
register_write_val(reg, ret & ~(ac->cor & re));
|
||||
|
||||
/* Mask based on the read enable size */
|
||||
ret &= re;
|
||||
|
||||
if (ac->post_read) {
|
||||
ret = ac->post_read(reg, ret);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
qemu_log("%s:%s: read of value %#" PRIx64 "\n", prefix,
|
||||
ac->name, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void register_reset(RegisterInfo *reg)
|
||||
{
|
||||
g_assert(reg);
|
||||
|
||||
if (!reg->data || !reg->access) {
|
||||
return;
|
||||
}
|
||||
|
||||
register_write_val(reg, reg->access->reset);
|
||||
}
|
||||
|
||||
void register_init(RegisterInfo *reg)
|
||||
{
|
||||
assert(reg);
|
||||
|
||||
if (!reg->data || !reg->access) {
|
||||
return;
|
||||
}
|
||||
|
||||
object_initialize((void *)reg, sizeof(*reg), TYPE_REGISTER);
|
||||
}
|
||||
|
||||
void register_write_memory(void *opaque, hwaddr addr,
|
||||
uint64_t value, unsigned size)
|
||||
{
|
||||
RegisterInfoArray *reg_array = opaque;
|
||||
RegisterInfo *reg = NULL;
|
||||
uint64_t we;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < reg_array->num_elements; i++) {
|
||||
if (reg_array->r[i]->access->addr == addr) {
|
||||
reg = reg_array->r[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!reg) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Write to unimplemented register at " \
|
||||
"address: %#" PRIx64 "\n", addr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Generate appropriate write enable mask */
|
||||
if (reg->data_size < size) {
|
||||
we = MAKE_64BIT_MASK(0, reg->data_size * 8);
|
||||
} else {
|
||||
we = MAKE_64BIT_MASK(0, size * 8);
|
||||
}
|
||||
|
||||
register_write(reg, value, we, reg_array->prefix,
|
||||
reg_array->debug);
|
||||
}
|
||||
|
||||
uint64_t register_read_memory(void *opaque, hwaddr addr,
|
||||
unsigned size)
|
||||
{
|
||||
RegisterInfoArray *reg_array = opaque;
|
||||
RegisterInfo *reg = NULL;
|
||||
uint64_t read_val;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < reg_array->num_elements; i++) {
|
||||
if (reg_array->r[i]->access->addr == addr) {
|
||||
reg = reg_array->r[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!reg) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "Read to unimplemented register at " \
|
||||
"address: %#" PRIx64 "\n", addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_val = register_read(reg, size * 8, reg_array->prefix,
|
||||
reg_array->debug);
|
||||
|
||||
return extract64(read_val, 0, size * 8);
|
||||
}
|
||||
|
||||
RegisterInfoArray *register_init_block32(DeviceState *owner,
|
||||
const RegisterAccessInfo *rae,
|
||||
int num, RegisterInfo *ri,
|
||||
uint32_t *data,
|
||||
const MemoryRegionOps *ops,
|
||||
bool debug_enabled,
|
||||
uint64_t memory_size)
|
||||
{
|
||||
const char *device_prefix = object_get_typename(OBJECT(owner));
|
||||
RegisterInfoArray *r_array = g_new0(RegisterInfoArray, 1);
|
||||
int i;
|
||||
|
||||
r_array->r = g_new0(RegisterInfo *, num);
|
||||
r_array->num_elements = num;
|
||||
r_array->debug = debug_enabled;
|
||||
r_array->prefix = device_prefix;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
int index = rae[i].addr / 4;
|
||||
RegisterInfo *r = &ri[index];
|
||||
|
||||
*r = (RegisterInfo) {
|
||||
.data = &data[index],
|
||||
.data_size = sizeof(uint32_t),
|
||||
.access = &rae[i],
|
||||
.opaque = owner,
|
||||
};
|
||||
register_init(r);
|
||||
|
||||
r_array->r[i] = r;
|
||||
}
|
||||
|
||||
memory_region_init_io(&r_array->mem, OBJECT(owner), ops, r_array,
|
||||
device_prefix, memory_size);
|
||||
|
||||
return r_array;
|
||||
}
|
||||
|
||||
void register_finalize_block(RegisterInfoArray *r_array)
|
||||
{
|
||||
object_unparent(OBJECT(&r_array->mem));
|
||||
g_free(r_array->r);
|
||||
g_free(r_array);
|
||||
}
|
||||
|
||||
static const TypeInfo register_info = {
|
||||
.name = TYPE_REGISTER,
|
||||
.parent = TYPE_DEVICE,
|
||||
};
|
||||
|
||||
static void register_register_types(void)
|
||||
{
|
||||
type_register_static(®ister_info);
|
||||
}
|
||||
|
||||
type_init(register_register_types)
|
||||
@@ -133,7 +133,7 @@ static const VMStateDescription vmstate_ads7846 = {
|
||||
}
|
||||
};
|
||||
|
||||
static int ads7846_init(SSISlave *d)
|
||||
static void ads7846_realize(SSISlave *d, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(d);
|
||||
ADS7846State *s = FROM_SSI_SLAVE(ADS7846State, d);
|
||||
@@ -152,14 +152,13 @@ static int ads7846_init(SSISlave *d)
|
||||
ads7846_int_update(s);
|
||||
|
||||
vmstate_register(NULL, -1, &vmstate_ads7846, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ads7846_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = ads7846_init;
|
||||
k->realize = ads7846_realize;
|
||||
k->transfer = ads7846_transfer;
|
||||
}
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@ static const GraphicHwOps ssd0323_ops = {
|
||||
.gfx_update = ssd0323_update_display,
|
||||
};
|
||||
|
||||
static int ssd0323_init(SSISlave *d)
|
||||
static void ssd0323_realize(SSISlave *d, Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(d);
|
||||
ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, d);
|
||||
@@ -375,14 +375,13 @@ static int ssd0323_init(SSISlave *d)
|
||||
|
||||
register_savevm(dev, "ssd0323_oled", -1, 1,
|
||||
ssd0323_save, ssd0323_load, s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ssd0323_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
SSISlaveClass *k = SSI_SLAVE_CLASS(klass);
|
||||
|
||||
k->init = ssd0323_init;
|
||||
k->realize = ssd0323_realize;
|
||||
k->transfer = ssd0323_transfer;
|
||||
k->cs_polarity = SSI_CS_HIGH;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ common-obj-$(CONFIG_PL330) += pl330.o
|
||||
common-obj-$(CONFIG_I82374) += i82374.o
|
||||
common-obj-$(CONFIG_I8257) += i8257.o
|
||||
common-obj-$(CONFIG_XILINX_AXI) += xilinx_axidma.o
|
||||
common-obj-$(CONFIG_ZYNQ_DEVCFG) += xlnx-zynq-devcfg.o
|
||||
common-obj-$(CONFIG_ETRAXFS) += etraxfs_dma.o
|
||||
common-obj-$(CONFIG_STP2000) += sparc32_dma.o
|
||||
common-obj-$(CONFIG_SUN4M) += sun4m_iommu.o
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user