Skip to content

Commit

Permalink
Merge remote-tracking branch 'rth/axp-next' into staging
Browse files Browse the repository at this point in the history
# By Richard Henderson
# Via Richard Henderson
* rth/axp-next:
  hw/alpha: Use SRM epoch
  hw/alpha: Drop latch_tmp hack
  exec: Support 64-bit operations in address_space_rw
  hw/alpha: Don't machine check on missing pci i/o
  hw/alpha: Don't use get_system_io

Message-id: 1373840171-25556-1-git-send-email-rth@twiddle.net
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
  • Loading branch information
Anthony Liguori committed Jul 15, 2013
2 parents 5699a02 + e605e96 commit a34001f
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 97 deletions.
68 changes: 56 additions & 12 deletions exec.c
Expand Up @@ -1896,15 +1896,37 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
return false;
}

static inline int memory_access_size(MemoryRegion *mr, int l, hwaddr addr)
static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
{
if (l >= 4 && (((addr & 3) == 0 || mr->ops->impl.unaligned))) {
return 4;
unsigned access_size_min = mr->ops->impl.min_access_size;
unsigned access_size_max = mr->ops->impl.max_access_size;

/* Regions are assumed to support 1-4 byte accesses unless
otherwise specified. */
if (access_size_min == 0) {
access_size_min = 1;
}
if (access_size_max == 0) {
access_size_max = 4;
}

/* Bound the maximum access by the alignment of the address. */
if (!mr->ops->impl.unaligned) {
unsigned align_size_max = addr & -addr;
if (align_size_max != 0 && align_size_max < access_size_max) {
access_size_max = align_size_max;
}
}
if (l >= 2 && (((addr & 1) == 0) || mr->ops->impl.unaligned)) {
return 2;

/* Don't attempt accesses larger than the maximum. */
if (l > access_size_max) {
l = access_size_max;
}
return 1;
/* ??? The users of this function are wrong, not supporting minimums larger
than the remaining length. C.f. memory.c:access_with_adjusted_size. */
assert(l >= access_size_min);

return l;
}

bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
Expand All @@ -1926,18 +1948,29 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
l = memory_access_size(mr, l, addr1);
/* XXX: could force current_cpu to NULL to avoid
potential bugs */
if (l == 4) {
switch (l) {
case 8:
/* 64 bit write access */
val = ldq_p(buf);
error |= io_mem_write(mr, addr1, val, 8);
break;
case 4:
/* 32 bit write access */
val = ldl_p(buf);
error |= io_mem_write(mr, addr1, val, 4);
} else if (l == 2) {
break;
case 2:
/* 16 bit write access */
val = lduw_p(buf);
error |= io_mem_write(mr, addr1, val, 2);
} else {
break;
case 1:
/* 8 bit write access */
val = ldub_p(buf);
error |= io_mem_write(mr, addr1, val, 1);
break;
default:
abort();
}
} else {
addr1 += memory_region_get_ram_addr(mr);
Expand All @@ -1950,18 +1983,29 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
if (!memory_access_is_direct(mr, is_write)) {
/* I/O case */
l = memory_access_size(mr, l, addr1);
if (l == 4) {
switch (l) {
case 8:
/* 64 bit read access */
error |= io_mem_read(mr, addr1, &val, 8);
stq_p(buf, val);
break;
case 4:
/* 32 bit read access */
error |= io_mem_read(mr, addr1, &val, 4);
stl_p(buf, val);
} else if (l == 2) {
break;
case 2:
/* 16 bit read access */
error |= io_mem_read(mr, addr1, &val, 2);
stw_p(buf, val);
} else {
break;
case 1:
/* 8 bit read access */
error |= io_mem_read(mr, addr1, &val, 1);
stb_p(buf, val);
break;
default:
abort();
}
} else {
/* RAM case */
Expand Down
2 changes: 1 addition & 1 deletion hw/alpha/alpha_sys.h
Expand Up @@ -14,7 +14,7 @@ PCIBus *typhoon_init(ram_addr_t, ISABus **, qemu_irq *, AlphaCPU *[4],
pci_map_irq_fn);

/* alpha_pci.c. */
extern const MemoryRegionOps alpha_pci_bw_io_ops;
extern const MemoryRegionOps alpha_pci_ignore_ops;
extern const MemoryRegionOps alpha_pci_conf1_ops;
extern const MemoryRegionOps alpha_pci_iack_ops;

Expand Down
4 changes: 3 additions & 1 deletion hw/alpha/dp264.c
Expand Up @@ -73,7 +73,9 @@ static void clipper_init(QEMUMachineInitArgs *args)
pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus,
clipper_pci_map_irq);

rtc_init(isa_bus, 1980, rtc_irq);
/* Since we have an SRM-compatible PALcode, use the SRM epoch. */
rtc_init(isa_bus, 1900, rtc_irq);

pit_init(isa_bus, 0x40, 0, NULL);
isa_create_simple(isa_bus, "i8042");

Expand Down
44 changes: 13 additions & 31 deletions hw/alpha/pci.c
Expand Up @@ -12,50 +12,32 @@
#include "sysemu/sysemu.h"


/* PCI IO reads/writes, to byte-word addressable memory. */
/* ??? Doesn't handle multiple PCI busses. */
/* Fallback for unassigned PCI I/O operations. Avoids MCHK. */

static uint64_t bw_io_read(void *opaque, hwaddr addr, unsigned size)
static uint64_t ignore_read(void *opaque, hwaddr addr, unsigned size)
{
switch (size) {
case 1:
return cpu_inb(addr);
case 2:
return cpu_inw(addr);
case 4:
return cpu_inl(addr);
}
abort();
return 0;
}

static void bw_io_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
static void ignore_write(void *opaque, hwaddr addr, uint64_t v, unsigned size)
{
switch (size) {
case 1:
cpu_outb(addr, val);
break;
case 2:
cpu_outw(addr, val);
break;
case 4:
cpu_outl(addr, val);
break;
default:
abort();
}
}

const MemoryRegionOps alpha_pci_bw_io_ops = {
.read = bw_io_read,
.write = bw_io_write,
const MemoryRegionOps alpha_pci_ignore_ops = {
.read = ignore_read,
.write = ignore_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 8,
},
.impl = {
.min_access_size = 1,
.max_access_size = 4,
.max_access_size = 8,
},
};


/* PCI config space reads/writes, to byte-word addressable memory. */
static uint64_t bw_conf1_read(void *opaque, hwaddr addr,
unsigned size)
Expand Down
72 changes: 20 additions & 52 deletions hw/alpha/typhoon.c
Expand Up @@ -51,9 +51,6 @@ typedef struct TyphoonState {
TyphoonPchip pchip;
MemoryRegion dchip_region;
MemoryRegion ram_region;

/* QEMU emulation state. */
uint32_t latch_tmp;
} TyphoonState;

/* Called when one of DRIR or DIM changes. */
Expand All @@ -76,10 +73,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
TyphoonState *s = opaque;
uint64_t ret = 0;

if (addr & 4) {
return s->latch_tmp;
}

switch (addr) {
case 0x0000:
/* CSC: Cchip System Configuration Register. */
Expand Down Expand Up @@ -199,7 +192,6 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
return -1;
}

s->latch_tmp = ret >> 32;
return ret;
}

Expand All @@ -214,10 +206,6 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
TyphoonState *s = opaque;
uint64_t ret = 0;

if (addr & 4) {
return s->latch_tmp;
}

switch (addr) {
case 0x0000:
/* WSBA0: Window Space Base Address Register. */
Expand Down Expand Up @@ -302,23 +290,14 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
return -1;
}

s->latch_tmp = ret >> 32;
return ret;
}

static void cchip_write(void *opaque, hwaddr addr,
uint64_t v32, unsigned size)
uint64_t val, unsigned size)
{
TyphoonState *s = opaque;
uint64_t val, oldval, newval;

if (addr & 4) {
val = v32 << 32 | s->latch_tmp;
addr ^= 4;
} else {
s->latch_tmp = v32;
return;
}
uint64_t oldval, newval;

switch (addr) {
case 0x0000:
Expand Down Expand Up @@ -471,18 +450,10 @@ static void dchip_write(void *opaque, hwaddr addr,
}

static void pchip_write(void *opaque, hwaddr addr,
uint64_t v32, unsigned size)
uint64_t val, unsigned size)
{
TyphoonState *s = opaque;
uint64_t val, oldval;

if (addr & 4) {
val = v32 << 32 | s->latch_tmp;
addr ^= 4;
} else {
s->latch_tmp = v32;
return;
}
uint64_t oldval;

switch (addr) {
case 0x0000:
Expand Down Expand Up @@ -585,12 +556,12 @@ static const MemoryRegionOps cchip_ops = {
.write = cchip_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4, /* ??? Should be 8. */
.min_access_size = 8,
.max_access_size = 8,
},
.impl = {
.min_access_size = 4,
.max_access_size = 4,
.min_access_size = 8,
.max_access_size = 8,
},
};

Expand All @@ -599,11 +570,11 @@ static const MemoryRegionOps dchip_ops = {
.write = dchip_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4, /* ??? Should be 8. */
.min_access_size = 8,
.max_access_size = 8,
},
.impl = {
.min_access_size = 4,
.min_access_size = 8,
.max_access_size = 8,
},
};
Expand All @@ -613,12 +584,12 @@ static const MemoryRegionOps pchip_ops = {
.write = pchip_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 4, /* ??? Should be 8. */
.min_access_size = 8,
.max_access_size = 8,
},
.impl = {
.min_access_size = 4,
.max_access_size = 4,
.min_access_size = 8,
.max_access_size = 8,
},
};

Expand Down Expand Up @@ -705,7 +676,6 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
const uint64_t MB = 1024 * 1024;
const uint64_t GB = 1024 * MB;
MemoryRegion *addr_space = get_system_memory();
MemoryRegion *addr_space_io = get_system_io();
DeviceState *dev;
TyphoonState *s;
PCIHostState *phb;
Expand Down Expand Up @@ -765,28 +735,26 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
&s->pchip.reg_mem);

/* Pchip0 PCI I/O, 0x801.FC00.0000, 32MB. */
/* ??? Ideally we drop the "system" i/o space on the floor and give the
PCI subsystem the full address space reserved by the chipset.
We can't do that until the MEM and IO paths in memory.c are unified. */
memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_bw_io_ops,
memory_region_init_io(&s->pchip.reg_io, OBJECT(s), &alpha_pci_ignore_ops,
NULL, "pci0-io", 32*MB);
memory_region_add_subregion(addr_space, 0x801fc000000ULL,
&s->pchip.reg_io);

b = pci_register_bus(dev, "pci",
typhoon_set_irq, sys_map_irq, s,
&s->pchip.reg_mem, addr_space_io, 0, 64, TYPE_PCI_BUS);
&s->pchip.reg_mem, &s->pchip.reg_io,
0, 64, TYPE_PCI_BUS);
phb->bus = b;

/* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB. */
memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops, b,
"pci0-iack", 64*MB);
memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
b, "pci0-iack", 64*MB);
memory_region_add_subregion(addr_space, 0x801f8000000ULL,
&s->pchip.reg_iack);

/* Pchip0 PCI configuration, 0x801.FE00.0000, 16MB. */
memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops, b,
"pci0-conf", 16*MB);
memory_region_init_io(&s->pchip.reg_conf, OBJECT(s), &alpha_pci_conf1_ops,
b, "pci0-conf", 16*MB);
memory_region_add_subregion(addr_space, 0x801fe000000ULL,
&s->pchip.reg_conf);

Expand All @@ -804,7 +772,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
{
qemu_irq isa_pci_irq, *isa_irqs;

*isa_bus = isa_bus_new(NULL, addr_space_io);
*isa_bus = isa_bus_new(NULL, &s->pchip.reg_io);
isa_pci_irq = *qemu_allocate_irqs(typhoon_set_isa_irq, s, 1);
isa_irqs = i8259_init(*isa_bus, isa_pci_irq);
isa_bus_irqs(*isa_bus, isa_irqs);
Expand Down

0 comments on commit a34001f

Please sign in to comment.