Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.8-20161017' into staging

ppc patch queue 2016-10-17

Highlights:
    * Significant rework of how PCI IO windows are placed for the
      pseries machine type
    * A number of extra tests added for ppc
    * Other tests clean up / fixed
    * Some cleanups to the XICS interrupt controller in preparation
      for the 'powernv' machine type

A number of the test changes aren't strictly in ppc related code, but
are included via my tree because they're primarily focused on
improving test coverage for ppc.

# gpg: Signature made Mon 17 Oct 2016 03:42:41 BST
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.8-20161017:
  spapr: Improved placement of PCI host bridges in guest memory map
  spapr_pci: Add a 64-bit MMIO window
  spapr: Adjust placement of PCI host bridge to allow > 1TiB RAM
  spapr_pci: Delegate placement of PCI host bridges to machine type
  libqos: Limit spapr-pci to 32-bit MMIO for now
  libqos: Correct error in PCI hole sizing for spapr
  libqos: Isolate knowledge of spapr memory map to qpci_init_spapr()
  ppc/xics: Split ICS into ics-base and ics class
  ppc/xics: Make the ICSState a list
  spapr: fix inheritance chain for default machine options
  target-ppc: implement vexts[bh]2w and vexts[bhw]2d
  tests/boot-sector: Increase time-out to 90 seconds
  tests/boot-sector: Use mkstemp() to create a unique file name
  tests/boot-sector: Use minimum length for the Forth boot script
  qtest: ask endianness of the target in qtest_init()
  tests: minor cleanups in usb-hcd-uhci-test

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2016-10-17 12:59:54 +01:00
28 changed files with 643 additions and 338 deletions
+8 -7
View File
@@ -50,16 +50,17 @@ xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR %#"PRIx3
xics_icp_eoi(int server, uint32_t xirr, uint32_t new_xirr) "icp_eoi: server %d given XIRR %#"PRIx32" new XIRR %#"PRIx32
xics_icp_irq(int server, int nr, uint8_t priority) "cpu %d trying to deliver irq %#"PRIx32" priority %#x"
xics_icp_raise(uint32_t xirr, uint8_t pending_priority) "raising IRQ new XIRR=%#x new pending priority=%#x"
xics_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq %#x]"
xics_ics_simple_set_irq_msi(int srcno, int nr) "set_irq_msi: srcno %d [irq %#x]"
xics_masked_pending(void) "set_irq_msi: masked pending"
xics_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq %#x]"
xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq %#x [src %d] server %#x prio %#x"
xics_ics_reject(int nr, int srcno) "reject irq %#x [src %d]"
xics_ics_eoi(int nr) "ics_eoi: irq %#x"
xics_alloc(int src, int irq) "source#%d, irq %d"
xics_alloc_block(int src, int first, int num, bool lsi, int align) "source#%d, first irq %d, %d irqs, lsi=%d, alignnum %d"
xics_ics_simple_set_irq_lsi(int srcno, int nr) "set_irq_lsi: srcno %d [irq %#x]"
xics_ics_simple_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_xive: irq %#x [src %d] server %#x prio %#x"
xics_ics_simple_reject(int nr, int srcno) "reject irq %#x [src %d]"
xics_ics_simple_eoi(int nr) "ics_eoi: irq %#x"
xics_alloc(int irq) "irq %d"
xics_alloc_block(int first, int num, bool lsi, int align) "first irq %d, %d irqs, lsi=%d, alignnum %d"
xics_ics_free(int src, int irq, int num) "Source#%d, first irq %d, %d irqs"
xics_ics_free_warn(int src, int irq) "Source#%d, irq %d is already free"
xics_icp_post_load(uint32_t server_no, uint32_t xirr, uint64_t addr, uint8_t pend) "server_no %d, xirr %#x, xirr_owner 0x%" PRIx64 ", pending %d"
# hw/intc/s390_flic_kvm.c
flic_create_device(int err) "flic: create device failed %d"
+142 -91
View File
File diff suppressed because it is too large Load Diff
+24 -13
View File
@@ -272,7 +272,7 @@ static void ics_kvm_set_irq(void *opaque, int srcno, int val)
static void ics_kvm_reset(DeviceState *dev)
{
ICSState *ics = ICS(dev);
ICSState *ics = ICS_SIMPLE(dev);
int i;
uint8_t flags[ics->nr_irqs];
@@ -293,7 +293,7 @@ static void ics_kvm_reset(DeviceState *dev)
static void ics_kvm_realize(DeviceState *dev, Error **errp)
{
ICSState *ics = ICS(dev);
ICSState *ics = ICS_SIMPLE(dev);
if (!ics->nr_irqs) {
error_setg(errp, "Number of interrupts needs to be greater 0");
@@ -306,7 +306,7 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp)
static void ics_kvm_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
ICSStateClass *icsc = ICS_CLASS(klass);
ICSStateClass *icsc = ICS_BASE_CLASS(klass);
dc->realize = ics_kvm_realize;
dc->reset = ics_kvm_reset;
@@ -315,8 +315,8 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo ics_kvm_info = {
.name = TYPE_KVM_ICS,
.parent = TYPE_ICS,
.name = TYPE_ICS_KVM,
.parent = TYPE_ICS_SIMPLE,
.instance_size = sizeof(ICSState),
.class_init = ics_kvm_class_init,
};
@@ -361,7 +361,13 @@ static void xics_kvm_cpu_setup(XICSState *xics, PowerPCCPU *cpu)
static void xics_kvm_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
Error **errp)
{
xics->nr_irqs = xics->ics->nr_irqs = nr_irqs;
ICSState *ics = QLIST_FIRST(&xics->ics);
/* This needs to be deprecated ... */
xics->nr_irqs = nr_irqs;
if (ics) {
ics->nr_irqs = nr_irqs;
}
}
static void xics_kvm_set_nr_servers(XICSState *xics, uint32_t nr_servers,
@@ -394,6 +400,7 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
{
KVMXICSState *xicskvm = XICS_SPAPR_KVM(dev);
XICSState *xics = XICS_COMMON(dev);
ICSState *ics;
int i, rc;
Error *error = NULL;
struct kvm_create_device xics_create_device = {
@@ -445,10 +452,12 @@ static void xics_kvm_realize(DeviceState *dev, Error **errp)
xicskvm->kernel_xics_fd = xics_create_device.fd;
object_property_set_bool(OBJECT(xics->ics), true, "realized", &error);
if (error) {
error_propagate(errp, error);
goto fail;
QLIST_FOREACH(ics, &xics->ics, list) {
object_property_set_bool(OBJECT(ics), true, "realized", &error);
if (error) {
error_propagate(errp, error);
goto fail;
}
}
assert(xics->nr_servers);
@@ -477,10 +486,12 @@ fail:
static void xics_kvm_initfn(Object *obj)
{
XICSState *xics = XICS_COMMON(obj);
ICSState *ics;
xics->ics = ICS(object_new(TYPE_KVM_ICS));
object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
xics->ics->xics = xics;
ics = ICS_SIMPLE(object_new(TYPE_ICS_KVM));
object_property_add_child(obj, "ics", OBJECT(ics), NULL);
ics->xics = xics;
QLIST_INSERT_HEAD(&xics->ics, ics, list);
}
static void xics_kvm_class_init(ObjectClass *oc, void *data)
+73 -43
View File
@@ -113,13 +113,17 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
{
ICSState *ics = spapr->xics->ics;
uint32_t nr, server, priority;
ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
uint32_t nr, srcno, server, priority;
if ((nargs != 3) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
if (!ics) {
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
nr = rtas_ld(args, 0);
server = xics_get_cpu_index_by_dt_id(rtas_ld(args, 1));
@@ -131,7 +135,8 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return;
}
ics_write_xive(ics, nr, server, priority, priority);
srcno = nr - ics->offset;
ics_simple_write_xive(ics, srcno, server, priority, priority);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
@@ -141,13 +146,17 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
{
ICSState *ics = spapr->xics->ics;
uint32_t nr;
ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
uint32_t nr, srcno;
if ((nargs != 1) || (nret != 3)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
if (!ics) {
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
nr = rtas_ld(args, 0);
@@ -157,8 +166,9 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
rtas_st(rets, 1, ics->irqs[nr - ics->offset].server);
rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority);
srcno = nr - ics->offset;
rtas_st(rets, 1, ics->irqs[srcno].server);
rtas_st(rets, 2, ics->irqs[srcno].priority);
}
static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
@@ -166,13 +176,17 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
{
ICSState *ics = spapr->xics->ics;
uint32_t nr;
ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
uint32_t nr, srcno;
if ((nargs != 1) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
if (!ics) {
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
nr = rtas_ld(args, 0);
@@ -181,8 +195,9 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return;
}
ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server, 0xff,
ics->irqs[nr - ics->offset].priority);
srcno = nr - ics->offset;
ics_simple_write_xive(ics, srcno, ics->irqs[srcno].server, 0xff,
ics->irqs[srcno].priority);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
@@ -192,13 +207,17 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
{
ICSState *ics = spapr->xics->ics;
uint32_t nr;
ICSState *ics = QLIST_FIRST(&spapr->xics->ics);
uint32_t nr, srcno;
if ((nargs != 1) || (nret != 1)) {
rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
return;
}
if (!ics) {
rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
return;
}
nr = rtas_ld(args, 0);
@@ -207,9 +226,10 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
return;
}
ics_write_xive(ics, nr, ics->irqs[nr - ics->offset].server,
ics->irqs[nr - ics->offset].saved_priority,
ics->irqs[nr - ics->offset].saved_priority);
srcno = nr - ics->offset;
ics_simple_write_xive(ics, srcno, ics->irqs[srcno].server,
ics->irqs[srcno].saved_priority,
ics->irqs[srcno].saved_priority);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
@@ -217,7 +237,13 @@ static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr,
static void xics_spapr_set_nr_irqs(XICSState *xics, uint32_t nr_irqs,
Error **errp)
{
xics->nr_irqs = xics->ics->nr_irqs = nr_irqs;
ICSState *ics = QLIST_FIRST(&xics->ics);
/* This needs to be deprecated ... */
xics->nr_irqs = nr_irqs;
if (ics) {
ics->nr_irqs = nr_irqs;
}
}
static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
@@ -240,6 +266,7 @@ static void xics_spapr_set_nr_servers(XICSState *xics, uint32_t nr_servers,
static void xics_spapr_realize(DeviceState *dev, Error **errp)
{
XICSState *xics = XICS_SPAPR(dev);
ICSState *ics;
Error *error = NULL;
int i;
@@ -261,10 +288,12 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
spapr_register_hypercall(H_EOI, h_eoi);
spapr_register_hypercall(H_IPOLL, h_ipoll);
object_property_set_bool(OBJECT(xics->ics), true, "realized", &error);
if (error) {
error_propagate(errp, error);
return;
QLIST_FOREACH(ics, &xics->ics, list) {
object_property_set_bool(OBJECT(ics), true, "realized", &error);
if (error) {
error_propagate(errp, error);
return;
}
}
for (i = 0; i < xics->nr_servers; i++) {
@@ -280,10 +309,12 @@ static void xics_spapr_realize(DeviceState *dev, Error **errp)
static void xics_spapr_initfn(Object *obj)
{
XICSState *xics = XICS_SPAPR(obj);
ICSState *ics;
xics->ics = ICS(object_new(TYPE_ICS));
object_property_add_child(obj, "ics", OBJECT(xics->ics), NULL);
xics->ics->xics = xics;
ics = ICS_SIMPLE(object_new(TYPE_ICS_SIMPLE));
object_property_add_child(obj, "ics", OBJECT(ics), NULL);
ics->xics = xics;
QLIST_INSERT_HEAD(&xics->ics, ics, list);
}
static void xics_spapr_class_init(ObjectClass *oc, void *data)
@@ -329,14 +360,15 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum)
return -1;
}
int xics_spapr_alloc(XICSState *xics, int src, int irq_hint, bool lsi,
Error **errp)
int xics_spapr_alloc(XICSState *xics, int irq_hint, bool lsi, Error **errp)
{
ICSState *ics = &xics->ics[src];
ICSState *ics = QLIST_FIRST(&xics->ics);
int irq;
if (!ics) {
return -1;
}
if (irq_hint) {
assert(src == xics_find_source(xics, irq_hint));
if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) {
error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint);
return -1;
@@ -352,7 +384,7 @@ int xics_spapr_alloc(XICSState *xics, int src, int irq_hint, bool lsi,
}
ics_set_irq_type(ics, irq - ics->offset, lsi);
trace_xics_alloc(src, irq);
trace_xics_alloc(irq);
return irq;
}
@@ -361,13 +393,16 @@ int xics_spapr_alloc(XICSState *xics, int src, int irq_hint, bool lsi,
* Allocate block of consecutive IRQs, and return the number of the first IRQ in
* the block. If align==true, aligns the first IRQ number to num.
*/
int xics_spapr_alloc_block(XICSState *xics, int src, int num, bool lsi,
bool align, Error **errp)
int xics_spapr_alloc_block(XICSState *xics, int num, bool lsi, bool align,
Error **errp)
{
ICSState *ics = QLIST_FIRST(&xics->ics);
int i, first = -1;
ICSState *ics = &xics->ics[src];
assert(src == 0);
if (!ics) {
return -1;
}
/*
* MSIMesage::data is used for storing VIRQ so
* it has to be aligned to num to support multiple
@@ -394,7 +429,7 @@ int xics_spapr_alloc_block(XICSState *xics, int src, int num, bool lsi,
}
first += ics->offset;
trace_xics_alloc_block(src, first, num, lsi, align);
trace_xics_alloc_block(first, num, lsi, align);
return first;
}
@@ -405,7 +440,7 @@ static void ics_free(ICSState *ics, int srcno, int num)
for (i = srcno; i < srcno + num; ++i) {
if (ICS_IRQ_FREE(ics, i)) {
trace_xics_ics_free_warn(ics - ics->xics->ics, i + ics->offset);
trace_xics_ics_free_warn(0, i + ics->offset);
}
memset(&ics->irqs[i], 0, sizeof(ICSIRQState));
}
@@ -413,15 +448,10 @@ static void ics_free(ICSState *ics, int srcno, int num)
void xics_spapr_free(XICSState *xics, int irq, int num)
{
int src = xics_find_source(xics, irq);
ICSState *ics = xics_find_source(xics, irq);
if (src >= 0) {
ICSState *ics = &xics->ics[src];
/* FIXME: implement multiple sources */
assert(src == 0);
trace_xics_ics_free(ics - xics->ics, irq, num);
if (ics) {
trace_xics_ics_free(0, irq, num);
ics_free(ics, irq - ics->offset, num);
}
}
+116 -2
View File
@@ -2370,6 +2370,56 @@ static HotpluggableCPUList *spapr_query_hotpluggable_cpus(MachineState *machine)
return head;
}
static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
unsigned n_dma, uint32_t *liobns, Error **errp)
{
/*
* New-style PHB window placement.
*
* Goals: Gives large (1TiB), naturally aligned 64-bit MMIO window
* for each PHB, in addition to 2GiB 32-bit MMIO and 64kiB PIO
* windows.
*
* Some guest kernels can't work with MMIO windows above 1<<46
* (64TiB), so we place up to 31 PHBs in the area 32TiB..64TiB
*
* 32TiB..(33TiB+1984kiB) contains the 64kiB PIO windows for each
* PHB stacked together. (32TiB+2GiB)..(32TiB+64GiB) contains the
* 2GiB 32-bit MMIO windows for each PHB. Then 33..64TiB has the
* 1TiB 64-bit MMIO windows for each PHB.
*/
const uint64_t base_buid = 0x800000020000000ULL;
const int max_phbs =
(SPAPR_PCI_LIMIT - SPAPR_PCI_BASE) / SPAPR_PCI_MEM64_WIN_SIZE - 1;
int i;
/* Sanity check natural alignments */
QEMU_BUILD_BUG_ON((SPAPR_PCI_BASE % SPAPR_PCI_MEM64_WIN_SIZE) != 0);
QEMU_BUILD_BUG_ON((SPAPR_PCI_LIMIT % SPAPR_PCI_MEM64_WIN_SIZE) != 0);
QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM64_WIN_SIZE % SPAPR_PCI_MEM32_WIN_SIZE) != 0);
QEMU_BUILD_BUG_ON((SPAPR_PCI_MEM32_WIN_SIZE % SPAPR_PCI_IO_WIN_SIZE) != 0);
/* Sanity check bounds */
QEMU_BUILD_BUG_ON((max_phbs * SPAPR_PCI_IO_WIN_SIZE) > SPAPR_PCI_MEM32_WIN_SIZE);
QEMU_BUILD_BUG_ON((max_phbs * SPAPR_PCI_MEM32_WIN_SIZE) > SPAPR_PCI_MEM64_WIN_SIZE);
if (index >= max_phbs) {
error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
max_phbs - 1);
return;
}
*buid = base_buid + index;
for (i = 0; i < n_dma; ++i) {
liobns[i] = SPAPR_PCI_LIOBN(index, i);
}
*pio = SPAPR_PCI_BASE + index * SPAPR_PCI_IO_WIN_SIZE;
*mmio32 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM32_WIN_SIZE;
*mmio64 = SPAPR_PCI_BASE + (index + 1) * SPAPR_PCI_MEM64_WIN_SIZE;
}
static void spapr_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -2406,6 +2456,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
mc->query_hotpluggable_cpus = spapr_query_hotpluggable_cpus;
fwc->get_dev_path = spapr_get_fw_dev_path;
nc->nmi_monitor_handler = spapr_nmi;
smc->phb_placement = spapr_phb_placement;
}
static const TypeInfo spapr_machine_info = {
@@ -2470,11 +2521,71 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", true);
/*
* pseries-2.7
*/
#define SPAPR_COMPAT_2_7 \
HW_COMPAT_2_7 \
#define SPAPR_COMPAT_2_7 \
HW_COMPAT_2_7 \
{ \
.driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
.property = "mem_win_size", \
.value = stringify(SPAPR_PCI_2_7_MMIO_WIN_SIZE),\
}, \
{ \
.driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
.property = "mem64_win_size", \
.value = "0", \
},
static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
unsigned n_dma, uint32_t *liobns, Error **errp)
{
/* Legacy PHB placement for pseries-2.7 and earlier machine types */
const uint64_t base_buid = 0x800000020000000ULL;
const hwaddr phb_spacing = 0x1000000000ULL; /* 64 GiB */
const hwaddr mmio_offset = 0xa0000000; /* 2 GiB + 512 MiB */
const hwaddr pio_offset = 0x80000000; /* 2 GiB */
const uint32_t max_index = 255;
const hwaddr phb0_alignment = 0x10000000000ULL; /* 1 TiB */
uint64_t ram_top = MACHINE(spapr)->ram_size;
hwaddr phb0_base, phb_base;
int i;
/* Do we have hotpluggable memory? */
if (MACHINE(spapr)->maxram_size > ram_top) {
/* Can't just use maxram_size, because there may be an
* alignment gap between normal and hotpluggable memory
* regions */
ram_top = spapr->hotplug_memory.base +
memory_region_size(&spapr->hotplug_memory.mr);
}
phb0_base = QEMU_ALIGN_UP(ram_top, phb0_alignment);
if (index > max_index) {
error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
max_index);
return;
}
*buid = base_buid + index;
for (i = 0; i < n_dma; ++i) {
liobns[i] = SPAPR_PCI_LIOBN(index, i);
}
phb_base = phb0_base + index * phb_spacing;
*pio = phb_base + pio_offset;
*mmio32 = phb_base + mmio_offset;
/*
* We don't set the 64-bit MMIO window, relying on the PHB's
* fallback behaviour of automatically splitting a large "32-bit"
* window into contiguous 32-bit and 64-bit windows
*/
}
static void spapr_machine_2_7_instance_options(MachineState *machine)
{
spapr_machine_2_8_instance_options(machine);
}
static void spapr_machine_2_7_class_options(MachineClass *mc)
@@ -2484,6 +2595,7 @@ static void spapr_machine_2_7_class_options(MachineClass *mc)
spapr_machine_2_8_class_options(mc);
smc->tcg_default_cpu = "POWER7";
SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_7);
smc->phb_placement = phb_placement_2_7;
}
DEFINE_SPAPR_MACHINE(2_7, "2.7", false);
@@ -2501,6 +2613,7 @@ DEFINE_SPAPR_MACHINE(2_7, "2.7", false);
static void spapr_machine_2_6_instance_options(MachineState *machine)
{
spapr_machine_2_7_instance_options(machine);
}
static void spapr_machine_2_6_class_options(MachineClass *mc)
@@ -2525,6 +2638,7 @@ DEFINE_SPAPR_MACHINE(2_6, "2.6", false);
static void spapr_machine_2_5_instance_options(MachineState *machine)
{
spapr_machine_2_6_instance_options(machine);
}
static void spapr_machine_2_5_class_options(MachineClass *mc)
+1 -1
View File
@@ -594,7 +594,7 @@ out_no_events:
void spapr_events_init(sPAPRMachineState *spapr)
{
QTAILQ_INIT(&spapr->pending_events);
spapr->check_exception_irq = xics_spapr_alloc(spapr->xics, 0, 0, false,
spapr->check_exception_irq = xics_spapr_alloc(spapr->xics, 0, false,
&error_fatal);
spapr->epow_notifier.notify = spapr_powerdown_req;
qemu_register_powerdown_notifier(&spapr->epow_notifier);
+65 -30
View File
@@ -363,7 +363,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
}
/* Allocate MSIs */
irq = xics_spapr_alloc_block(spapr->xics, 0, req_num, false,
irq = xics_spapr_alloc_block(spapr->xics, req_num, false,
ret_intr_type == RTAS_TYPE_MSI, &err);
if (err) {
error_reportf_err(err, "Can't allocate MSIs for device %x: ",
@@ -1311,32 +1311,27 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1;
if (sphb->index != (uint32_t)-1) {
hwaddr windows_base;
sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
Error *local_err = NULL;
if ((sphb->buid != (uint64_t)-1) || (sphb->dma_liobn[0] != (uint32_t)-1)
|| (sphb->dma_liobn[1] != (uint32_t)-1 && windows_supported == 2)
|| (sphb->mem_win_addr != (hwaddr)-1)
|| (sphb->mem64_win_addr != (hwaddr)-1)
|| (sphb->io_win_addr != (hwaddr)-1)) {
error_setg(errp, "Either \"index\" or other parameters must"
" be specified for PAPR PHB, not both");
return;
}
if (sphb->index > SPAPR_PCI_MAX_INDEX) {
error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
SPAPR_PCI_MAX_INDEX);
smc->phb_placement(spapr, sphb->index,
&sphb->buid, &sphb->io_win_addr,
&sphb->mem_win_addr, &sphb->mem64_win_addr,
windows_supported, sphb->dma_liobn, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index;
for (i = 0; i < windows_supported; ++i) {
sphb->dma_liobn[i] = SPAPR_PCI_LIOBN(sphb->index, i);
}
windows_base = SPAPR_PCI_WINDOW_BASE
+ sphb->index * SPAPR_PCI_WINDOW_SPACING;
sphb->mem_win_addr = windows_base + SPAPR_PCI_MMIO_WIN_OFF;
sphb->io_win_addr = windows_base + SPAPR_PCI_IO_WIN_OFF;
}
if (sphb->buid == (uint64_t)-1) {
@@ -1360,6 +1355,38 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
return;
}
if (sphb->mem64_win_size != 0) {
if (sphb->mem64_win_addr == (hwaddr)-1) {
error_setg(errp,
"64-bit memory window address not specified for PHB");
return;
}
if (sphb->mem_win_size > SPAPR_PCI_MEM32_WIN_SIZE) {
error_setg(errp, "32-bit memory window of size 0x%"HWADDR_PRIx
" (max 2 GiB)", sphb->mem_win_size);
return;
}
if (sphb->mem64_win_pciaddr == (hwaddr)-1) {
/* 64-bit window defaults to identity mapping */
sphb->mem64_win_pciaddr = sphb->mem64_win_addr;
}
} else if (sphb->mem_win_size > SPAPR_PCI_MEM32_WIN_SIZE) {
/*
* For compatibility with old configuration, if no 64-bit MMIO
* window is specified, but the ordinary (32-bit) memory
* window is specified as > 2GiB, we treat it as a 2GiB 32-bit
* window, with a 64-bit MMIO window following on immediately
* afterwards
*/
sphb->mem64_win_size = sphb->mem_win_size - SPAPR_PCI_MEM32_WIN_SIZE;
sphb->mem64_win_addr = sphb->mem_win_addr + SPAPR_PCI_MEM32_WIN_SIZE;
sphb->mem64_win_pciaddr =
SPAPR_PCI_MEM_WIN_BUS_OFFSET + SPAPR_PCI_MEM32_WIN_SIZE;
sphb->mem_win_size = SPAPR_PCI_MEM32_WIN_SIZE;
}
if (spapr_pci_find_phb(spapr, sphb->buid)) {
error_setg(errp, "PCI host bridges must have unique BUIDs");
return;
@@ -1373,12 +1400,19 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
sprintf(namebuf, "%s.mmio", sphb->dtbusname);
memory_region_init(&sphb->memspace, OBJECT(sphb), namebuf, UINT64_MAX);
sprintf(namebuf, "%s.mmio-alias", sphb->dtbusname);
memory_region_init_alias(&sphb->memwindow, OBJECT(sphb),
sprintf(namebuf, "%s.mmio32-alias", sphb->dtbusname);
memory_region_init_alias(&sphb->mem32window, OBJECT(sphb),
namebuf, &sphb->memspace,
SPAPR_PCI_MEM_WIN_BUS_OFFSET, sphb->mem_win_size);
memory_region_add_subregion(get_system_memory(), sphb->mem_win_addr,
&sphb->memwindow);
&sphb->mem32window);
sprintf(namebuf, "%s.mmio64-alias", sphb->dtbusname);
memory_region_init_alias(&sphb->mem64window, OBJECT(sphb),
namebuf, &sphb->memspace,
sphb->mem64_win_pciaddr, sphb->mem64_win_size);
memory_region_add_subregion(get_system_memory(), sphb->mem64_win_addr,
&sphb->mem64window);
/* Initialize IO regions */
sprintf(namebuf, "%s.io", sphb->dtbusname);
@@ -1445,8 +1479,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
uint32_t irq;
Error *local_err = NULL;
irq = xics_spapr_alloc_block(spapr->xics, 0, 1, true, false,
&local_err);
irq = xics_spapr_alloc_block(spapr->xics, 1, true, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
error_prepend(errp, "can't allocate LSIs: ");
@@ -1531,7 +1564,12 @@ static Property spapr_phb_properties[] = {
DEFINE_PROP_UINT32("liobn64", sPAPRPHBState, dma_liobn[1], -1),
DEFINE_PROP_UINT64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
DEFINE_PROP_UINT64("mem_win_size", sPAPRPHBState, mem_win_size,
SPAPR_PCI_MMIO_WIN_SIZE),
SPAPR_PCI_MEM32_WIN_SIZE),
DEFINE_PROP_UINT64("mem64_win_addr", sPAPRPHBState, mem64_win_addr, -1),
DEFINE_PROP_UINT64("mem64_win_size", sPAPRPHBState, mem64_win_size,
SPAPR_PCI_MEM64_WIN_SIZE),
DEFINE_PROP_UINT64("mem64_win_pciaddr", sPAPRPHBState, mem64_win_pciaddr,
-1),
DEFINE_PROP_UINT64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
DEFINE_PROP_UINT64("io_win_size", sPAPRPHBState, io_win_size,
SPAPR_PCI_IO_WIN_SIZE),
@@ -1767,10 +1805,6 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
int bus_off, i, j, ret;
char nodename[FDT_NAME_MAX];
uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
const uint64_t mmiosize = memory_region_size(&phb->memwindow);
const uint64_t w32max = (1ULL << 32) - SPAPR_PCI_MEM_WIN_BUS_OFFSET;
const uint64_t w32size = MIN(w32max, mmiosize);
const uint64_t w64size = (mmiosize > w32size) ? (mmiosize - w32size) : 0;
struct {
uint32_t hi;
uint64_t child;
@@ -1785,15 +1819,16 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
{
cpu_to_be32(b_ss(2)), cpu_to_be64(SPAPR_PCI_MEM_WIN_BUS_OFFSET),
cpu_to_be64(phb->mem_win_addr),
cpu_to_be64(w32size),
cpu_to_be64(phb->mem_win_size),
},
{
cpu_to_be32(b_ss(3)), cpu_to_be64(1ULL << 32),
cpu_to_be64(phb->mem_win_addr + w32size),
cpu_to_be64(w64size)
cpu_to_be32(b_ss(3)), cpu_to_be64(phb->mem64_win_pciaddr),
cpu_to_be64(phb->mem64_win_addr),
cpu_to_be64(phb->mem64_win_size),
},
};
const unsigned sizeof_ranges = (w64size ? 3 : 2) * sizeof(ranges[0]);
const unsigned sizeof_ranges =
(phb->mem64_win_size ? 3 : 2) * sizeof(ranges[0]);
uint64_t bus_reg[] = { cpu_to_be64(phb->buid), 0 };
uint32_t interrupt_map_mask[] = {
cpu_to_be32(b_ddddd(-1)|b_fff(0)), 0x0, 0x0, cpu_to_be32(-1)};
+1 -1
View File
@@ -453,7 +453,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
dev->qdev.id = id;
}
dev->irq = xics_spapr_alloc(spapr->xics, 0, dev->irq, false, &local_err);
dev->irq = xics_spapr_alloc(spapr->xics, dev->irq, false, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
+13 -12
View File
@@ -53,8 +53,10 @@ struct sPAPRPHBState {
bool dr_enabled;
MemoryRegion memspace, iospace;
hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size;
MemoryRegion memwindow, iowindow, msiwindow;
hwaddr mem_win_addr, mem_win_size, mem64_win_addr, mem64_win_size;
uint64_t mem64_win_pciaddr;
hwaddr io_win_addr, io_win_size;
MemoryRegion mem32window, mem64window, iowindow, msiwindow;
uint32_t dma_liobn[SPAPR_PCI_DMA_MAX_WINDOWS];
hwaddr dma_win_addr, dma_win_size;
@@ -79,18 +81,17 @@ struct sPAPRPHBState {
uint32_t numa_node;
};
#define SPAPR_PCI_MAX_INDEX 255
#define SPAPR_PCI_BASE_BUID 0x800000020000000ULL
#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
#define SPAPR_PCI_MEM32_WIN_SIZE \
((1ULL << 32) - SPAPR_PCI_MEM_WIN_BUS_OFFSET)
#define SPAPR_PCI_MEM64_WIN_SIZE 0x10000000000ULL /* 1 TiB */
#define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL
#define SPAPR_PCI_WINDOW_SPACING 0x1000000000ULL
#define SPAPR_PCI_MMIO_WIN_OFF 0xA0000000
#define SPAPR_PCI_MMIO_WIN_SIZE (SPAPR_PCI_WINDOW_SPACING - \
SPAPR_PCI_MEM_WIN_BUS_OFFSET)
#define SPAPR_PCI_IO_WIN_OFF 0x80000000
/* Without manual configuration, all PCI outbound windows will be
* within this range */
#define SPAPR_PCI_BASE (1ULL << 45) /* 32 TiB */
#define SPAPR_PCI_LIMIT (1ULL << 46) /* 64 TiB */
#define SPAPR_PCI_2_7_MMIO_WIN_SIZE 0xf80000000
#define SPAPR_PCI_IO_WIN_SIZE 0x10000
#define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL
+4
View File
@@ -40,6 +40,10 @@ struct sPAPRMachineClass {
bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */
bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */
const char *tcg_default_cpu; /* which (TCG) CPU to simulate by default */
void (*phb_placement)(sPAPRMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
hwaddr *mmio32, hwaddr *mmio64,
unsigned n_dma, uint32_t *liobns, Error **errp);
};
/**
+24 -16
View File
@@ -85,7 +85,7 @@ struct XICSState {
uint32_t nr_servers;
uint32_t nr_irqs;
ICPState *ss;
ICSState *ics;
QLIST_HEAD(, ICSState) ics;
};
#define TYPE_ICP "icp"
@@ -111,6 +111,7 @@ struct ICPState {
DeviceState parent_obj;
/*< public >*/
CPUState *cs;
ICSState *xirr_owner;
uint32_t xirr;
uint8_t pending_priority;
uint8_t mfrr;
@@ -118,22 +119,29 @@ struct ICPState {
bool cap_irq_xics_enabled;
};
#define TYPE_ICS "ics"
#define ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS)
#define TYPE_ICS_BASE "ics-base"
#define ICS_BASE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_BASE)
#define TYPE_KVM_ICS "icskvm"
#define KVM_ICS(obj) OBJECT_CHECK(ICSState, (obj), TYPE_KVM_ICS)
/* Retain ics for sPAPR for migration from existing sPAPR guests */
#define TYPE_ICS_SIMPLE "ics"
#define ICS_SIMPLE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE)
#define ICS_CLASS(klass) \
OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS)
#define ICS_GET_CLASS(obj) \
OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS)
#define TYPE_ICS_KVM "icskvm"
#define ICS_KVM(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_KVM)
#define ICS_BASE_CLASS(klass) \
OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS_BASE)
#define ICS_BASE_GET_CLASS(obj) \
OBJECT_GET_CLASS(ICSStateClass, (obj), TYPE_ICS_BASE)
struct ICSStateClass {
DeviceClass parent_class;
void (*pre_save)(ICSState *s);
int (*post_load)(ICSState *s, int version_id);
void (*reject)(ICSState *s, uint32_t irq);
void (*resend)(ICSState *s);
void (*eoi)(ICSState *s, uint32_t irq);
};
struct ICSState {
@@ -145,6 +153,7 @@ struct ICSState {
qemu_irq *qirqs;
ICSIRQState *irqs;
XICSState *xics;
QLIST_ENTRY(ICSState) list;
};
static inline bool ics_valid_irq(ICSState *ics, uint32_t nr)
@@ -172,10 +181,9 @@ struct ICSIRQState {
#define XICS_IRQS_SPAPR 1024
qemu_irq xics_get_qirq(XICSState *icp, int irq);
int xics_spapr_alloc(XICSState *icp, int src, int irq_hint, bool lsi,
Error **errp);
int xics_spapr_alloc_block(XICSState *icp, int src, int num, bool lsi,
bool align, Error **errp);
int xics_spapr_alloc(XICSState *icp, int irq_hint, bool lsi, Error **errp);
int xics_spapr_alloc_block(XICSState *icp, int num, bool lsi, bool align,
Error **errp);
void xics_spapr_free(XICSState *icp, int irq, int num);
void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu);
@@ -190,11 +198,11 @@ uint32_t icp_accept(ICPState *ss);
uint32_t icp_ipoll(ICPState *ss, uint32_t *mfrr);
void icp_eoi(XICSState *icp, int server, uint32_t xirr);
void ics_write_xive(ICSState *ics, int nr, int server,
uint8_t priority, uint8_t saved_priority);
void ics_simple_write_xive(ICSState *ics, int nr, int server,
uint8_t priority, uint8_t saved_priority);
void ics_set_irq_type(ICSState *ics, int srcno, bool lsi);
int xics_find_source(XICSState *icp, int irq);
ICSState *xics_find_source(XICSState *icp, int irq);
#endif /* XICS_H */
+7
View File
@@ -537,6 +537,13 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
qtest_send_prefix(chr);
qtest_send(chr, "OK\n");
} else if (strcmp(words[0], "endianness") == 0) {
qtest_send_prefix(chr);
#if defined(TARGET_WORDS_BIGENDIAN)
qtest_sendf(chr, "OK big\n");
#else
qtest_sendf(chr, "OK little\n");
#endif
#ifdef TARGET_PPC64
} else if (strcmp(words[0], "rtas") == 0) {
uint64_t res, args, ret;
+5
View File
@@ -267,6 +267,11 @@ DEF_HELPER_3(vinsertb, void, avr, avr, i32)
DEF_HELPER_3(vinserth, void, avr, avr, i32)
DEF_HELPER_3(vinsertw, void, avr, avr, i32)
DEF_HELPER_3(vinsertd, void, avr, avr, i32)
DEF_HELPER_2(vextsb2w, void, avr, avr)
DEF_HELPER_2(vextsh2w, void, avr, avr)
DEF_HELPER_2(vextsb2d, void, avr, avr)
DEF_HELPER_2(vextsh2d, void, avr, avr)
DEF_HELPER_2(vextsw2d, void, avr, avr)
DEF_HELPER_2(vupkhpx, void, avr, avr)
DEF_HELPER_2(vupklpx, void, avr, avr)
DEF_HELPER_2(vupkhsb, void, avr, avr)
+15
View File
@@ -1934,6 +1934,21 @@ VEXTRACT(uw, u32)
VEXTRACT(d, u64)
#undef VEXTRACT
#define VEXT_SIGNED(name, element, mask, cast, recast) \
void helper_##name(ppc_avr_t *r, ppc_avr_t *b) \
{ \
int i; \
VECTOR_FOR_INORDER_I(i, element) { \
r->element[i] = (recast)((cast)(b->element[i] & mask)); \
} \
}
VEXT_SIGNED(vextsb2w, s32, UINT8_MAX, int8_t, int32_t)
VEXT_SIGNED(vextsb2d, s64, UINT8_MAX, int8_t, int64_t)
VEXT_SIGNED(vextsh2w, s32, UINT16_MAX, int16_t, int32_t)
VEXT_SIGNED(vextsh2d, s64, UINT16_MAX, int16_t, int64_t)
VEXT_SIGNED(vextsw2d, s64, UINT32_MAX, int32_t, int64_t)
#undef VEXT_SIGNED
#define VSPLTI(suffix, element, splat_type) \
void helper_vspltis##suffix(ppc_avr_t *r, uint32_t splat) \
{ \
+5
View File
@@ -815,6 +815,11 @@ GEN_VXFORM_NOA(vclzb, 1, 28)
GEN_VXFORM_NOA(vclzh, 1, 29)
GEN_VXFORM_NOA(vclzw, 1, 30)
GEN_VXFORM_NOA(vclzd, 1, 31)
GEN_VXFORM_NOA_2(vextsb2w, 1, 24, 16)
GEN_VXFORM_NOA_2(vextsh2w, 1, 24, 17)
GEN_VXFORM_NOA_2(vextsb2d, 1, 24, 24)
GEN_VXFORM_NOA_2(vextsh2d, 1, 24, 25)
GEN_VXFORM_NOA_2(vextsw2d, 1, 24, 26)
GEN_VXFORM_NOA_2(vctzb, 1, 24, 28)
GEN_VXFORM_NOA_2(vctzh, 1, 24, 29)
GEN_VXFORM_NOA_2(vctzw, 1, 24, 30)
+5
View File
@@ -215,6 +215,11 @@ GEN_VXFORM_DUAL_INV(vspltish, vinserth, 6, 13, 0x00000000, 0x100000,
GEN_VXFORM_DUAL_INV(vspltisw, vinsertw, 6, 14, 0x00000000, 0x100000,
PPC_ALTIVEC),
GEN_VXFORM_300_EXT(vinsertd, 6, 15, 0x100000),
GEN_VXFORM_300_EO(vextsb2w, 0x01, 0x18, 0x10),
GEN_VXFORM_300_EO(vextsh2w, 0x01, 0x18, 0x11),
GEN_VXFORM_300_EO(vextsb2d, 0x01, 0x18, 0x18),
GEN_VXFORM_300_EO(vextsh2d, 0x01, 0x18, 0x19),
GEN_VXFORM_300_EO(vextsw2d, 0x01, 0x18, 0x1A),
GEN_VXFORM_300_EO(vctzb, 0x01, 0x18, 0x1C),
GEN_VXFORM_300_EO(vctzh, 0x01, 0x18, 0x1D),
GEN_VXFORM_300_EO(vctzw, 0x01, 0x18, 0x1E),
+1 -1
View File
@@ -112,7 +112,7 @@ typedef struct {
g_assert_cmpstr(ACPI_ASSERT_CMP_str, ==, expected); \
} while (0)
static const char *disk = "tests/acpi-test-disk.raw";
static char disk[] = "tests/acpi-test-disk-XXXXXX";
static const char *data_dir = "tests/acpi-test-data";
#ifdef CONFIG_IASL
static const char *iasl = stringify(CONFIG_IASL);
+16 -9
View File
@@ -69,25 +69,32 @@ static uint8_t boot_sector[0x7e000] = {
};
/* Create boot disk file. */
int boot_sector_init(const char *fname)
int boot_sector_init(char *fname)
{
FILE *f = fopen(fname, "w");
int fd, ret;
size_t len = sizeof boot_sector;
if (!f) {
fd = mkstemp(fname);
if (fd < 0) {
fprintf(stderr, "Couldn't open \"%s\": %s", fname, strerror(errno));
return 1;
}
/* For Open Firmware based system, we can use a Forth script instead */
if (strcmp(qtest_get_arch(), "ppc64") == 0) {
memset(boot_sector, ' ', sizeof boot_sector);
sprintf((char *)boot_sector, "\\ Bootscript\n%x %x c! %x %x c!\n",
len = sprintf((char *)boot_sector, "\\ Bootscript\n%x %x c! %x %x c!\n",
LOW(SIGNATURE), BOOT_SECTOR_ADDRESS + SIGNATURE_OFFSET,
HIGH(SIGNATURE), BOOT_SECTOR_ADDRESS + SIGNATURE_OFFSET + 1);
}
fwrite(boot_sector, 1, sizeof boot_sector, f);
fclose(f);
ret = write(fd, boot_sector, len);
close(fd);
if (ret != len) {
fprintf(stderr, "Could not write \"%s\"", fname);
return 1;
}
return 0;
}
@@ -99,9 +106,9 @@ void boot_sector_test(void)
uint16_t signature;
int i;
/* Wait at most 1 minute */
/* Wait at most 90 seconds */
#define TEST_DELAY (1 * G_USEC_PER_SEC / 10)
#define TEST_CYCLES MAX((60 * G_USEC_PER_SEC / TEST_DELAY), 1)
#define TEST_CYCLES MAX((90 * G_USEC_PER_SEC / TEST_DELAY), 1)
/* Poll until code has run and modified memory. Once it has we know BIOS
* initialization is done. TODO: check that IP reached the halt
+2 -2
View File
@@ -14,8 +14,8 @@
#ifndef TEST_BOOT_SECTOR_H
#define TEST_BOOT_SECTOR_H
/* Create boot disk file. */
int boot_sector_init(const char *fname);
/* Create boot disk file. fname must be a suitable string for mkstemp() */
int boot_sector_init(char *fname);
/* Loop until signature in memory is OK. */
void boot_sector_test(void);
+2 -1
View File
@@ -38,7 +38,8 @@ static const TestCase test_cases[] = {
{ "ppc", "prep", 0x80000000, .bswap = true },
{ "ppc", "bamboo", 0xe8000000, .bswap = true, .superio = "i82378" },
{ "ppc64", "mac99", 0xf2000000, .bswap = true, .superio = "i82378" },
{ "ppc64", "pseries", 0x10080000000ULL,
{ "ppc64", "pseries", (1ULL << 45), .bswap = true, .superio = "i82378" },
{ "ppc64", "pseries-2.7", 0x10080000000ULL,
.bswap = true, .superio = "i82378" },
{ "sh4", "r2d", 0xfe240000, .superio = "i82378" },
{ "sh4eb", "r2d", 0xfe240000, .bswap = true, .superio = "i82378" },

Some files were not shown because too many files have changed in this diff Show More