* [Qemu-devel] [PATCH v2 0/6] pci: 64bit support
@ 2012-02-29 11:45 Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 1/6] output: add 64bit hex print support Gerd Hoffmann
` (5 more replies)
0 siblings, 6 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2012-02-29 11:45 UTC (permalink / raw)
To: seabios; +Cc: qemu-devel, Gerd Hoffmann
Hi,
New revision of my 64bit pci patches. This is what I'm using to play
with 64bit PCI bars (ivshmem + qxl devices) and bridge support (patches
from mst).
Changes in v2:
* tried to reduce the stack footprint of 64bit hex number printing.
* changed patch splitting to make them (hopefully) more readable.
* full support for bridges with 64bit memory windows, even nested.
Also availabe from:
git://git.kraxel.org/seabios pci64
enjoy,
Gerd
Gerd Hoffmann (6):
output: add 64bit hex print support
pci: split device discovery into multiple steps
pci: 64bit support.
pci: bridges can have two regions too
pci: fix bridge ressource allocation.
pci: add prefmem64
src/acpi-dsdt.dsl | 7 ++
src/acpi-dsdt.hex | 72 ++++++++++++---
src/config.h | 2 +
src/output.c | 23 ++++-
src/pci.h | 14 ++-
src/pciinit.c | 272 ++++++++++++++++++++++++++++++++++++++---------------
6 files changed, 294 insertions(+), 96 deletions(-)
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 1/6] output: add 64bit hex print support
2012-02-29 11:45 [Qemu-devel] [PATCH v2 0/6] pci: 64bit support Gerd Hoffmann
@ 2012-02-29 11:45 ` Gerd Hoffmann
2012-03-05 15:23 ` [Qemu-devel] [SeaBIOS] " Kevin O'Connor
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 2/6] pci: split device discovery into multiple steps Gerd Hoffmann
` (4 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Gerd Hoffmann @ 2012-02-29 11:45 UTC (permalink / raw)
To: seabios; +Cc: qemu-devel, Gerd Hoffmann
---
src/output.c | 23 +++++++++++++++++++++--
1 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/output.c b/src/output.c
index bdde7cc..32cbcaa 100644
--- a/src/output.c
+++ b/src/output.c
@@ -249,6 +249,7 @@ bvprintf(struct putcinfo *action, const char *fmt, va_list args)
const char *n = s+1;
int field_width = 0;
int spacepad = 1;
+ int is64 = 0;
for (;;) {
c = GET_GLOBAL(*(u8*)n);
if (!isdigit(c))
@@ -264,6 +265,11 @@ bvprintf(struct putcinfo *action, const char *fmt, va_list args)
n++;
c = GET_GLOBAL(*(u8*)n);
}
+ if (c == 'l') {
+ is64 = 1;
+ n++;
+ c = GET_GLOBAL(*(u8*)n);
+ }
s32 val;
const char *sarg;
switch (c) {
@@ -289,8 +295,21 @@ bvprintf(struct putcinfo *action, const char *fmt, va_list args)
field_width = 8;
spacepad = 0;
case 'x':
- val = va_arg(args, s32);
- puthex(action, val, field_width, spacepad);
+ if (is64) {
+ val = va_arg(args, s32);
+ u32 upper = va_arg(args, s32);
+ if (upper) {
+ if (field_width < 8)
+ field_width = 8;
+ puthex(action, upper, field_width - 8, spacepad);
+ puthex(action, val, 8, 0);
+ } else {
+ puthex(action, val, field_width, spacepad);
+ }
+ } else {
+ val = va_arg(args, s32);
+ puthex(action, val, field_width, spacepad);
+ }
break;
case 'c':
val = va_arg(args, int);
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 2/6] pci: split device discovery into multiple steps
2012-02-29 11:45 [Qemu-devel] [PATCH v2 0/6] pci: 64bit support Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 1/6] output: add 64bit hex print support Gerd Hoffmann
@ 2012-02-29 11:45 ` Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 3/6] pci: 64bit support Gerd Hoffmann
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2012-02-29 11:45 UTC (permalink / raw)
To: seabios; +Cc: qemu-devel, Gerd Hoffmann
First bridge init, next pci bar discovery, finally pci bar ressource
allocation. Needed because we need to figure whenever we can map 64bit
bars above 4G before doing ressource allocation.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
src/pciinit.c | 39 ++++++++++++++++++++++++++++++++-------
1 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/src/pciinit.c b/src/pciinit.c
index 9f3fdd4..652564c 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -368,22 +368,28 @@ static void pci_bios_check_devices(struct pci_bus *busses)
{
dprintf(1, "PCI: check devices\n");
- // Calculate resources needed for regular (non-bus) devices.
struct pci_device *pci;
+ struct pci_bus *bus;
+ int i;
+
+ // init pci bridges
foreachpci(pci) {
- if (pci->class == PCI_CLASS_BRIDGE_PCI) {
- busses[pci->secondary_bus].bus_dev = pci;
+ if (pci->class != PCI_CLASS_BRIDGE_PCI)
+ continue;
+ bus = &busses[pci->secondary_bus];
+ bus->bus_dev = pci;
+ }
+
+ // discover pci bars
+ foreachpci(pci) {
+ if (pci->class == PCI_CLASS_BRIDGE_PCI)
continue;
- }
- struct pci_bus *bus = &busses[pci_bdf_to_bus(pci->bdf)];
- int i;
for (i = 0; i < PCI_NUM_REGIONS; i++) {
u32 val, size;
pci_bios_get_bar(pci, i, &val, &size);
if (val == 0)
continue;
- pci_bios_bus_reserve(bus, pci_addr_to_type(val), size);
pci->bars[i].addr = val;
pci->bars[i].size = size;
pci->bars[i].is64 = (!(val & PCI_BASE_ADDRESS_SPACE_IO) &&
@@ -395,6 +401,25 @@ static void pci_bios_check_devices(struct pci_bus *busses)
}
}
+ // alloc ressources for pci bars
+ foreachpci(pci) {
+ if (pci->class == PCI_CLASS_BRIDGE_PCI)
+ continue;
+ bus = &busses[pci_bdf_to_bus(pci->bdf)];
+ for (i = 0; i < PCI_NUM_REGIONS; i++) {
+ enum pci_region_type type;
+ if (pci->bars[i].addr == 0)
+ continue;
+
+ type = pci_addr_to_type(pci->bars[i].addr);
+ pci_bios_bus_reserve(bus, type,
+ pci->bars[i].size);
+
+ if (pci->bars[i].is64)
+ i++;
+ }
+ }
+
// Propagate required bus resources to parent busses.
int secondary_bus;
for (secondary_bus=MaxPCIBus; secondary_bus>0; secondary_bus--) {
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 3/6] pci: 64bit support.
2012-02-29 11:45 [Qemu-devel] [PATCH v2 0/6] pci: 64bit support Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 1/6] output: add 64bit hex print support Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 2/6] pci: split device discovery into multiple steps Gerd Hoffmann
@ 2012-02-29 11:45 ` Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 4/6] pci: bridges can have two regions too Gerd Hoffmann
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2012-02-29 11:45 UTC (permalink / raw)
To: seabios; +Cc: qemu-devel, Gerd Hoffmann
Makes pciinit.c 64bit aware. Use 64bit everywhere. Support discovery
and configuration of 64bit bars, with non-zero upper32 bits. While
being at it introduce a struct pci_bar which can be passed easily.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
src/pci.h | 14 ++++--
src/pciinit.c | 126 +++++++++++++++++++++++++++++++++++----------------------
2 files changed, 87 insertions(+), 53 deletions(-)
diff --git a/src/pci.h b/src/pci.h
index a2a5a4c..46f162e 100644
--- a/src/pci.h
+++ b/src/pci.h
@@ -39,6 +39,14 @@ void pci_config_maskw(u16 bdf, u32 addr, u16 off, u16 on);
struct pci_device *pci_find_device(u16 vendid, u16 devid);
struct pci_device *pci_find_class(u16 classid);
+struct pci_bar {
+ u64 addr;
+ u64 size;
+ int is64:1,
+ ismem:1,
+ isprefetch:1;
+};
+
struct pci_device {
u16 bdf;
u8 rootbus;
@@ -51,11 +59,7 @@ struct pci_device {
u8 prog_if, revision;
u8 header_type;
u8 secondary_bus;
- struct {
- u32 addr;
- u32 size;
- int is64;
- } bars[PCI_NUM_REGIONS];
+ struct pci_bar bars[PCI_NUM_REGIONS];
// Local information on device.
int have_driver;
diff --git a/src/pciinit.c b/src/pciinit.c
index 652564c..aa391a0 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -35,12 +35,12 @@ struct pci_bus {
struct {
/* pci region stats */
u32 count[32 - PCI_MEM_INDEX_SHIFT];
- u32 sum, max;
+ u64 sum, max;
/* seconday bus region sizes */
- u32 size;
+ u64 size;
/* pci region assignments */
- u32 bases[32 - PCI_MEM_INDEX_SHIFT];
- u32 base;
+ u64 bases[32 - PCI_MEM_INDEX_SHIFT];
+ u64 base;
} r[PCI_REGION_TYPE_COUNT];
struct pci_device *bus_dev;
};
@@ -65,13 +65,13 @@ static u32 pci_index_to_size(int index, enum pci_region_type type)
return 0x1 << (index + shift);
}
-static enum pci_region_type pci_addr_to_type(u32 addr)
+static enum pci_region_type pci_addr_to_type(struct pci_bus *bus, struct pci_bar *bar)
{
- if (addr & PCI_BASE_ADDRESS_SPACE_IO)
+ if (!bar->ismem)
return PCI_REGION_TYPE_IO;
- if (addr & PCI_BASE_ADDRESS_MEM_PREFETCH)
- return PCI_REGION_TYPE_PREFMEM;
- return PCI_REGION_TYPE_MEM;
+ if (!bar->isprefetch)
+ return PCI_REGION_TYPE_MEM;
+ return PCI_REGION_TYPE_PREFMEM;
}
static u32 pci_bar(struct pci_device *pci, int region_num)
@@ -86,9 +86,15 @@ static u32 pci_bar(struct pci_device *pci, int region_num)
}
static void
-pci_set_io_region_addr(struct pci_device *pci, int region_num, u32 addr)
+pci_set_io_region_addr(struct pci_device *pci, int region_num,
+ u64 addr, int is64)
{
- pci_config_writel(pci->bdf, pci_bar(pci, region_num), addr);
+ u32 ofs = pci_bar(pci, region_num);
+
+ pci_config_writel(pci->bdf, ofs, addr & 0xffffffff);
+ if (is64) {
+ pci_config_writel(pci->bdf, ofs + 4, addr >> 32);
+ }
}
@@ -141,10 +147,10 @@ static const struct pci_device_id pci_isa_bridge_tbl[] = {
static void storage_ide_init(struct pci_device *pci, void *arg)
{
/* IDE: we map it as in ISA mode */
- pci_set_io_region_addr(pci, 0, PORT_ATA1_CMD_BASE);
- pci_set_io_region_addr(pci, 1, PORT_ATA1_CTRL_BASE);
- pci_set_io_region_addr(pci, 2, PORT_ATA2_CMD_BASE);
- pci_set_io_region_addr(pci, 3, PORT_ATA2_CTRL_BASE);
+ pci_set_io_region_addr(pci, 0, PORT_ATA1_CMD_BASE, 0);
+ pci_set_io_region_addr(pci, 1, PORT_ATA1_CTRL_BASE, 0);
+ pci_set_io_region_addr(pci, 2, PORT_ATA2_CMD_BASE, 0);
+ pci_set_io_region_addr(pci, 3, PORT_ATA2_CTRL_BASE, 0);
}
/* PIIX3/PIIX4 IDE */
@@ -158,13 +164,13 @@ static void piix_ide_init(struct pci_device *pci, void *arg)
static void pic_ibm_init(struct pci_device *pci, void *arg)
{
/* PIC, IBM, MPIC & MPIC2 */
- pci_set_io_region_addr(pci, 0, 0x80800000 + 0x00040000);
+ pci_set_io_region_addr(pci, 0, 0x80800000 + 0x00040000, 0);
}
static void apple_macio_init(struct pci_device *pci, void *arg)
{
/* macio bridge */
- pci_set_io_region_addr(pci, 0, 0x80800000);
+ pci_set_io_region_addr(pci, 0, 0x80800000, 0);
}
static const struct pci_device_id pci_class_tbl[] = {
@@ -330,14 +336,14 @@ static u32 pci_size_roundup(u32 size)
}
static void
-pci_bios_get_bar(struct pci_device *pci, int bar, u32 *val, u32 *size)
+pci_bios_get_bar(struct pci_device *pci, int nr, struct pci_bar *bar)
{
- u32 ofs = pci_bar(pci, bar);
+ u32 ofs = pci_bar(pci, nr);
u16 bdf = pci->bdf;
u32 old = pci_config_readl(bdf, ofs);
- u32 mask;
+ u64 mask;
- if (bar == PCI_ROM_SLOT) {
+ if (nr == PCI_ROM_SLOT) {
mask = PCI_ROM_ADDRESS_MASK;
pci_config_writel(bdf, ofs, mask);
} else {
@@ -347,12 +353,38 @@ pci_bios_get_bar(struct pci_device *pci, int bar, u32 *val, u32 *size)
mask = PCI_BASE_ADDRESS_MEM_MASK;
pci_config_writel(bdf, ofs, ~0);
}
- *val = pci_config_readl(bdf, ofs);
+ bar->addr = pci_config_readl(bdf, ofs);
pci_config_writel(bdf, ofs, old);
- *size = (~(*val & mask)) + 1;
+ if ((bar->addr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
+ bar->ismem = 1;
+ if ((bar->addr & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+ PCI_BASE_ADDRESS_MEM_TYPE_64)
+ bar->is64 = 1;
+ if (bar->addr & PCI_BASE_ADDRESS_MEM_PREFETCH)
+ bar->isprefetch = 1;
+ }
+ if (bar->is64) {
+ u32 hold, high;
+ hold = pci_config_readl(bdf, ofs + 4);
+ pci_config_writel(bdf, ofs + 4, ~0);
+ high = pci_config_readl(bdf, ofs + 4);
+ pci_config_writel(bdf, ofs + 4, hold);
+ bar->addr |= ((u64)high << 32);
+ mask |= ((u64)0xffffffff << 32);
+ bar->size = (~(bar->addr & mask)) + 1;
+ } else if (bar->addr != 0) {
+ bar->size = (~(bar->addr & mask) & 0xffffffff) + 1;
+ }
+ if (bar->addr != 0) {
+ dprintf(1, " %d: addr %llx size %llx %s %s%s\n", nr,
+ bar->addr, bar->size,
+ bar->ismem ? "mem" : "io",
+ bar->is64 ? "64bit" : "32bit",
+ bar->isprefetch ? " prefetchable" : "");
+ }
}
-static void pci_bios_bus_reserve(struct pci_bus *bus, int type, u32 size)
+static void pci_bios_bus_reserve(struct pci_bus *bus, int type, u64 size)
{
u32 index;
@@ -384,18 +416,14 @@ static void pci_bios_check_devices(struct pci_bus *busses)
foreachpci(pci) {
if (pci->class == PCI_CLASS_BRIDGE_PCI)
continue;
+ dprintf(1, "PCI: check device bdf=%02x:%02x.%x\n",
+ pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
+ pci_bdf_to_fn(pci->bdf));
for (i = 0; i < PCI_NUM_REGIONS; i++) {
- u32 val, size;
- pci_bios_get_bar(pci, i, &val, &size);
- if (val == 0)
+ pci_bios_get_bar(pci, i, &pci->bars[i]);
+ if (pci->bars[i].addr == 0)
continue;
- pci->bars[i].addr = val;
- pci->bars[i].size = size;
- pci->bars[i].is64 = (!(val & PCI_BASE_ADDRESS_SPACE_IO) &&
- (val & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
- == PCI_BASE_ADDRESS_MEM_TYPE_64);
-
if (pci->bars[i].is64)
i++;
}
@@ -411,7 +439,7 @@ static void pci_bios_check_devices(struct pci_bus *busses)
if (pci->bars[i].addr == 0)
continue;
- type = pci_addr_to_type(pci->bars[i].addr);
+ type = pci_addr_to_type(bus, &pci->bars[i]);
pci_bios_bus_reserve(bus, type,
pci->bars[i].size);
@@ -429,7 +457,7 @@ static void pci_bios_check_devices(struct pci_bus *busses)
struct pci_bus *parent = &busses[pci_bdf_to_bus(s->bus_dev->bdf)];
int type;
for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
- u32 limit = (type == PCI_REGION_TYPE_IO) ?
+ u64 limit = (type == PCI_REGION_TYPE_IO) ?
PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
s->r[type].size = s->r[type].sum;
if (s->r[type].size < limit)
@@ -437,7 +465,8 @@ static void pci_bios_check_devices(struct pci_bus *busses)
s->r[type].size = pci_size_roundup(s->r[type].size);
pci_bios_bus_reserve(parent, type, s->r[type].size);
}
- dprintf(1, "PCI: secondary bus %d sizes: io %x, mem %x, prefmem %x\n",
+ dprintf(1, "PCI: secondary bus %d sizes: "
+ "io %llx, mem %llx, prefmem %llx\n",
secondary_bus,
s->r[PCI_REGION_TYPE_IO].size,
s->r[PCI_REGION_TYPE_MEM].size,
@@ -474,19 +503,20 @@ static int pci_bios_init_root_regions(struct pci_bus *bus, u32 start, u32 end)
static void pci_bios_init_bus_bases(struct pci_bus *bus)
{
- u32 base, newbase, size;
+ u64 base, newbase, size;
int type, i;
for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
- dprintf(1, " type %s max %x sum %x base %x\n", region_type_name[type],
- bus->r[type].max, bus->r[type].sum, bus->r[type].base);
+ dprintf(1, " type %s max %llx sum %llx base %llx\n",
+ region_type_name[type], bus->r[type].max,
+ bus->r[type].sum, bus->r[type].base);
base = bus->r[type].base;
for (i = ARRAY_SIZE(bus->r[type].count)-1; i >= 0; i--) {
size = pci_index_to_size(i, type);
if (!bus->r[type].count[i])
continue;
newbase = base + size * bus->r[type].count[i];
- dprintf(1, " size %8x: %d bar(s), %8x -> %8x\n",
+ dprintf(1, " size %8llx: %d bar(s), %8llx -> %8llx\n",
size, bus->r[type].count[i], base, newbase - 1);
bus->r[type].bases[i] = base;
base = newbase;
@@ -530,8 +560,8 @@ static void pci_bios_map_devices(struct pci_bus *busses)
dprintf(1, "PCI: init bases bus %d (secondary)\n", secondary_bus);
pci_bios_init_bus_bases(s);
- u32 base = s->r[PCI_REGION_TYPE_IO].base;
- u32 limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
+ u64 base = s->r[PCI_REGION_TYPE_IO].base;
+ u64 limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
pci_config_writeb(bdf, PCI_IO_BASE, base >> PCI_IO_SHIFT);
pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
@@ -564,15 +594,15 @@ static void pci_bios_map_devices(struct pci_bus *busses)
if (pci->bars[i].addr == 0)
continue;
- int type = pci_addr_to_type(pci->bars[i].addr);
- u32 addr = pci_bios_bus_get_addr(bus, type, pci->bars[i].size);
- dprintf(1, " bar %d, addr %x, size %x [%s]\n",
- i, addr, pci->bars[i].size, region_type_name[type]);
- pci_set_io_region_addr(pci, i, addr);
+ int type = pci_addr_to_type(bus, &pci->bars[i]);
+ u64 addr = pci_bios_bus_get_addr(bus, type, pci->bars[i].size);
+ dprintf(1, " bar %d, addr %llx, size %llx [%s]\n",
+ i, addr, pci->bars[i].size,
+ region_type_name[type]);
+ pci_set_io_region_addr(pci, i, addr, pci->bars[i].is64);
if (pci->bars[i].is64) {
i++;
- pci_set_io_region_addr(pci, i, 0);
}
}
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 4/6] pci: bridges can have two regions too
2012-02-29 11:45 [Qemu-devel] [PATCH v2 0/6] pci: 64bit support Gerd Hoffmann
` (2 preceding siblings ...)
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 3/6] pci: 64bit support Gerd Hoffmann
@ 2012-02-29 11:45 ` Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 5/6] pci: fix bridge ressource allocation Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 6/6] pci: add prefmem64 Gerd Hoffmann
5 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2012-02-29 11:45 UTC (permalink / raw)
To: seabios; +Cc: qemu-devel, Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
src/pciinit.c | 20 ++++++++------------
1 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/src/pciinit.c b/src/pciinit.c
index aa391a0..33b9bf7 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -402,7 +402,7 @@ static void pci_bios_check_devices(struct pci_bus *busses)
struct pci_device *pci;
struct pci_bus *bus;
- int i;
+ int i, num_regions;
// init pci bridges
foreachpci(pci) {
@@ -414,12 +414,11 @@ static void pci_bios_check_devices(struct pci_bus *busses)
// discover pci bars
foreachpci(pci) {
- if (pci->class == PCI_CLASS_BRIDGE_PCI)
- continue;
+ num_regions = (pci->class == PCI_CLASS_BRIDGE_PCI) ? 2 : PCI_NUM_REGIONS;
dprintf(1, "PCI: check device bdf=%02x:%02x.%x\n",
pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
pci_bdf_to_fn(pci->bdf));
- for (i = 0; i < PCI_NUM_REGIONS; i++) {
+ for (i = 0; i < num_regions; i++) {
pci_bios_get_bar(pci, i, &pci->bars[i]);
if (pci->bars[i].addr == 0)
continue;
@@ -431,10 +430,9 @@ static void pci_bios_check_devices(struct pci_bus *busses)
// alloc ressources for pci bars
foreachpci(pci) {
- if (pci->class == PCI_CLASS_BRIDGE_PCI)
- continue;
+ num_regions = (pci->class == PCI_CLASS_BRIDGE_PCI) ? 2 : PCI_NUM_REGIONS;
bus = &busses[pci_bdf_to_bus(pci->bdf)];
- for (i = 0; i < PCI_NUM_REGIONS; i++) {
+ for (i = 0; i < num_regions; i++) {
enum pci_region_type type;
if (pci->bars[i].addr == 0)
continue;
@@ -545,7 +543,7 @@ static void pci_bios_map_devices(struct pci_bus *busses)
pci_bios_init_bus_bases(&busses[0]);
// Map regions on each secondary bus.
- int secondary_bus;
+ int secondary_bus, num_regions, i;
for (secondary_bus=1; secondary_bus<=MaxPCIBus; secondary_bus++) {
struct pci_bus *s = &busses[secondary_bus];
if (!s->bus_dev)
@@ -583,14 +581,12 @@ static void pci_bios_map_devices(struct pci_bus *busses)
// Map regions on each device.
struct pci_device *pci;
foreachpci(pci) {
- if (pci->class == PCI_CLASS_BRIDGE_PCI)
- continue;
+ num_regions = (pci->class == PCI_CLASS_BRIDGE_PCI) ? 2 : PCI_NUM_REGIONS;
u16 bdf = pci->bdf;
dprintf(1, "PCI: map device bdf=%02x:%02x.%x\n"
, pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
struct pci_bus *bus = &busses[pci_bdf_to_bus(bdf)];
- int i;
- for (i = 0; i < PCI_NUM_REGIONS; i++) {
+ for (i = 0; i < num_regions; i++) {
if (pci->bars[i].addr == 0)
continue;
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 5/6] pci: fix bridge ressource allocation.
2012-02-29 11:45 [Qemu-devel] [PATCH v2 0/6] pci: 64bit support Gerd Hoffmann
` (3 preceding siblings ...)
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 4/6] pci: bridges can have two regions too Gerd Hoffmann
@ 2012-02-29 11:45 ` Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 6/6] pci: add prefmem64 Gerd Hoffmann
5 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2012-02-29 11:45 UTC (permalink / raw)
To: seabios; +Cc: qemu-devel, Gerd Hoffmann
The patch changes the bridge ressource allocation: Unused memory
windows are disabled: If none of the devices connected to the bridge
has -- say -- I/O bars, then the I/O memory window is turned off. This
implies that bridges without devices don't get any ressources assigned.
The pci bridge spec wants us behave that way (figured while looking at
drivers/pci/setup-bus.c in the linux kernel source tree).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
src/pciinit.c | 43 +++++++++++++++++++++++++++++++++----------
1 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/src/pciinit.c b/src/pciinit.c
index 33b9bf7..a03e17c 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -457,6 +457,8 @@ static void pci_bios_check_devices(struct pci_bus *busses)
for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
u64 limit = (type == PCI_REGION_TYPE_IO) ?
PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
+ if (s->r[type].sum == 0)
+ continue;
s->r[type].size = s->r[type].sum;
if (s->r[type].size < limit)
s->r[type].size = limit;
@@ -505,6 +507,8 @@ static void pci_bios_init_bus_bases(struct pci_bus *bus)
int type, i;
for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
+ if (bus->r[type].sum == 0)
+ continue;
dprintf(1, " type %s max %llx sum %llx base %llx\n",
region_type_name[type], bus->r[type].max,
bus->r[type].sum, bus->r[type].base);
@@ -522,9 +526,10 @@ static void pci_bios_init_bus_bases(struct pci_bus *bus)
}
}
-static u32 pci_bios_bus_get_addr(struct pci_bus *bus, int type, u32 size)
+static u64 pci_bios_bus_get_addr(struct pci_bus *bus, int type, u64 size)
{
- u32 index, addr;
+ u32 index;
+ u64 addr;
index = pci_size_to_index(size, type);
addr = bus->r[type].bases[index];
@@ -552,30 +557,48 @@ static void pci_bios_map_devices(struct pci_bus *busses)
struct pci_bus *parent = &busses[pci_bdf_to_bus(bdf)];
int type;
for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
+ if (s->r[type].sum == 0)
+ continue;
s->r[type].base = pci_bios_bus_get_addr(
parent, type, s->r[type].size);
}
dprintf(1, "PCI: init bases bus %d (secondary)\n", secondary_bus);
pci_bios_init_bus_bases(s);
- u64 base = s->r[PCI_REGION_TYPE_IO].base;
- u64 limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
+ u64 base, limit;
+ if (s->r[PCI_REGION_TYPE_IO].sum) {
+ base = s->r[PCI_REGION_TYPE_IO].base;
+ limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
+ } else {
+ base = PCI_BRIDGE_IO_MIN;
+ limit = 0;
+ }
pci_config_writeb(bdf, PCI_IO_BASE, base >> PCI_IO_SHIFT);
pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
- base = s->r[PCI_REGION_TYPE_MEM].base;
- limit = base + s->r[PCI_REGION_TYPE_MEM].size - 1;
+ if (s->r[PCI_REGION_TYPE_MEM].sum) {
+ base = s->r[PCI_REGION_TYPE_MEM].base;
+ limit = base + s->r[PCI_REGION_TYPE_MEM].size - 1;
+ } else {
+ base = PCI_BRIDGE_MEM_MIN;
+ limit = 0;
+ }
pci_config_writew(bdf, PCI_MEMORY_BASE, base >> PCI_MEMORY_SHIFT);
pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> PCI_MEMORY_SHIFT);
- base = s->r[PCI_REGION_TYPE_PREFMEM].base;
- limit = base + s->r[PCI_REGION_TYPE_PREFMEM].size - 1;
+ if (s->r[PCI_REGION_TYPE_PREFMEM].sum) {
+ base = s->r[PCI_REGION_TYPE_PREFMEM].base;
+ limit = base + s->r[PCI_REGION_TYPE_PREFMEM].size - 1;
+ } else {
+ base = PCI_BRIDGE_MEM_MIN;
+ limit = 0;
+ }
pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, base >> PCI_PREF_MEMORY_SHIFT);
pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> PCI_PREF_MEMORY_SHIFT);
- pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, 0);
- pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, 0);
+ pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, base >> 32);
+ pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, base >> 32);
}
// Map regions on each device.
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [Qemu-devel] [PATCH v2 6/6] pci: add prefmem64
2012-02-29 11:45 [Qemu-devel] [PATCH v2 0/6] pci: 64bit support Gerd Hoffmann
` (4 preceding siblings ...)
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 5/6] pci: fix bridge ressource allocation Gerd Hoffmann
@ 2012-02-29 11:45 ` Gerd Hoffmann
5 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2012-02-29 11:45 UTC (permalink / raw)
To: seabios; +Cc: qemu-devel, Gerd Hoffmann
This patch adds a prefmem64 region for 64bit pci prefmem bars which
we'll go map above 4G. This will happen when either the device is on
the root bus or it is behind a bridge supporting 64bit memory windows
and all prefmem bars of all devices hooked up using that bridge are
64bit capable.
---
src/acpi-dsdt.dsl | 7 +++++
src/acpi-dsdt.hex | 72 +++++++++++++++++++++++++++++++++++++++++++---------
src/config.h | 2 +
src/pciinit.c | 72 +++++++++++++++++++++++++++++++++++++++++++---------
4 files changed, 127 insertions(+), 26 deletions(-)
diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl
index 7082b65..c17e947 100644
--- a/src/acpi-dsdt.dsl
+++ b/src/acpi-dsdt.dsl
@@ -175,6 +175,13 @@ DefinitionBlock (
0x00000000, // Address Translation Offset
0x1EC00000, // Address Length
,, , AddressRangeMemory, TypeStatic)
+ QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
+ 0x00000000, // Address Space Granularity
+ 0x8000000000, // Address Range Minimum
+ 0xFFFFFFFFFF, // Address Range Maximum
+ 0x00000000, // Address Translation Offset
+ 0x8000000000, // Address Length
+ ,, , AddressRangeMemory, TypeStatic)
})
}
}
diff --git a/src/acpi-dsdt.hex b/src/acpi-dsdt.hex
index 5dc7bb4..2393827 100644
--- a/src/acpi-dsdt.hex
+++ b/src/acpi-dsdt.hex
@@ -3,12 +3,12 @@ static unsigned char AmlCode[] = {
0x53,
0x44,
0x54,
-0xd3,
-0x10,
+0x1,
+0x11,
0x0,
0x0,
0x1,
-0x2d,
+0x1e,
0x42,
0x58,
0x50,
@@ -31,9 +31,9 @@ static unsigned char AmlCode[] = {
0x4e,
0x54,
0x4c,
-0x28,
-0x5,
-0x10,
+0x23,
+0x1,
+0x9,
0x20,
0x10,
0x49,
@@ -110,16 +110,16 @@ static unsigned char AmlCode[] = {
0x47,
0x42,
0x10,
-0x44,
-0x81,
+0x42,
+0x84,
0x5f,
0x53,
0x42,
0x5f,
0x5b,
0x82,
-0x4c,
-0x80,
+0x4a,
+0x83,
0x50,
0x43,
0x49,
@@ -2064,10 +2064,10 @@ static unsigned char AmlCode[] = {
0x52,
0x53,
0x11,
-0x42,
-0x7,
+0x40,
+0xa,
0xa,
-0x6e,
+0x9c,
0x88,
0xd,
0x0,
@@ -2176,6 +2176,52 @@ static unsigned char AmlCode[] = {
0x0,
0xc0,
0x1e,
+0x8a,
+0x2b,
+0x0,
+0x0,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x80,
+0x0,
+0x0,
+0x0,
0x79,
0x0,
0x10,
diff --git a/src/config.h b/src/config.h
index b0187a4..5850476 100644
--- a/src/config.h
+++ b/src/config.h
@@ -47,6 +47,8 @@
#define BUILD_PCIMEM_START 0xe0000000
#define BUILD_PCIMEM_END 0xfec00000 /* IOAPIC is mapped at */
+#define BUILD_PCIMEM64_START 0x8000000000ULL
+#define BUILD_PCIMEM64_END 0xFFFFFFFFFFULL
#define BUILD_IOAPIC_ADDR 0xfec00000
#define BUILD_HPET_ADDRESS 0xfed00000
diff --git a/src/pciinit.c b/src/pciinit.c
index a03e17c..b3eaf86 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -22,13 +22,15 @@ enum pci_region_type {
PCI_REGION_TYPE_IO,
PCI_REGION_TYPE_MEM,
PCI_REGION_TYPE_PREFMEM,
+ PCI_REGION_TYPE_PREFMEM64,
PCI_REGION_TYPE_COUNT,
};
static const char *region_type_name[] = {
- [ PCI_REGION_TYPE_IO ] = "io",
- [ PCI_REGION_TYPE_MEM ] = "mem",
- [ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
+ [ PCI_REGION_TYPE_IO ] = "io",
+ [ PCI_REGION_TYPE_MEM ] = "mem",
+ [ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
+ [ PCI_REGION_TYPE_PREFMEM64 ] = "prefmem64",
};
struct pci_bus {
@@ -42,7 +44,9 @@ struct pci_bus {
u64 bases[32 - PCI_MEM_INDEX_SHIFT];
u64 base;
} r[PCI_REGION_TYPE_COUNT];
+ int use_prefmem64;
struct pci_device *bus_dev;
+ struct pci_bus *parent;
};
static int pci_size_to_index(u32 size, enum pci_region_type type)
@@ -67,11 +71,19 @@ static u32 pci_index_to_size(int index, enum pci_region_type type)
static enum pci_region_type pci_addr_to_type(struct pci_bus *bus, struct pci_bar *bar)
{
+ struct pci_bus *b;
+
if (!bar->ismem)
return PCI_REGION_TYPE_IO;
if (!bar->isprefetch)
return PCI_REGION_TYPE_MEM;
- return PCI_REGION_TYPE_PREFMEM;
+ if (!bar->is64)
+ return PCI_REGION_TYPE_PREFMEM;
+ for (b = bus; b != NULL && b->bus_dev != NULL; b = b->parent) {
+ if (!bus->use_prefmem64)
+ return PCI_REGION_TYPE_PREFMEM;
+ }
+ return PCI_REGION_TYPE_PREFMEM64;
}
static u32 pci_bar(struct pci_device *pci, int region_num)
@@ -409,12 +421,26 @@ static void pci_bios_check_devices(struct pci_bus *busses)
if (pci->class != PCI_CLASS_BRIDGE_PCI)
continue;
bus = &busses[pci->secondary_bus];
+ bus->parent = &busses[pci_bdf_to_bus(pci->bdf)];
bus->bus_dev = pci;
+ u32 pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
+ if (!pmem) {
+ pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0xfff0fff0);
+ pmem = pci_config_readl(pci->bdf, PCI_PREF_MEMORY_BASE);
+ pci_config_writel(pci->bdf, PCI_PREF_MEMORY_BASE, 0x0);
+ }
+ if ((pmem & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
+ dprintf(1, "PCI: bridge bdf=%02x:%02x.%x supports prefmem64\n",
+ pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
+ pci_bdf_to_fn(pci->bdf));
+ bus->use_prefmem64 = 1;
+ }
}
// discover pci bars
foreachpci(pci) {
num_regions = (pci->class == PCI_CLASS_BRIDGE_PCI) ? 2 : PCI_NUM_REGIONS;
+ bus = &busses[pci_bdf_to_bus(pci->bdf)];
dprintf(1, "PCI: check device bdf=%02x:%02x.%x\n",
pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf),
pci_bdf_to_fn(pci->bdf));
@@ -423,6 +449,15 @@ static void pci_bios_check_devices(struct pci_bus *busses)
if (pci->bars[i].addr == 0)
continue;
+ if (pci->bars[i].ismem && pci->bars[i].isprefetch && !pci->bars[i].is64) {
+ /* 32bit prefmem bar found -- disable 64bit prefmem
+ * on all bridges all the way up to the root bus */
+ struct pci_bus *b;
+ for (b = bus; b != NULL; b = b->parent) {
+ b->use_prefmem64 = 0;
+ }
+ }
+
if (pci->bars[i].is64)
i++;
}
@@ -466,22 +501,29 @@ static void pci_bios_check_devices(struct pci_bus *busses)
pci_bios_bus_reserve(parent, type, s->r[type].size);
}
dprintf(1, "PCI: secondary bus %d sizes: "
- "io %llx, mem %llx, prefmem %llx\n",
+ "io %llx, mem %llx, prefmem %llx, prefmem64 %llx\n",
secondary_bus,
s->r[PCI_REGION_TYPE_IO].size,
s->r[PCI_REGION_TYPE_MEM].size,
- s->r[PCI_REGION_TYPE_PREFMEM].size);
+ s->r[PCI_REGION_TYPE_PREFMEM].size,
+ s->r[PCI_REGION_TYPE_PREFMEM64].size);
}
}
#define ROOT_BASE(top, sum, max) ALIGN_DOWN((top)-(sum),(max) ?: 1)
// Setup region bases (given the regions' size and alignment)
-static int pci_bios_init_root_regions(struct pci_bus *bus, u32 start, u32 end)
+static int pci_bios_init_root_regions(struct pci_bus *bus)
{
+ u32 start = BUILD_PCIMEM_START;
+ u32 end = BUILD_PCIMEM_END;
+ u64 start64 = BUILD_PCIMEM64_START;
+ u64 end64 = BUILD_PCIMEM64_END;
+
bus->r[PCI_REGION_TYPE_IO].base = 0xc000;
int reg1 = PCI_REGION_TYPE_PREFMEM, reg2 = PCI_REGION_TYPE_MEM;
+ int reg3 = PCI_REGION_TYPE_PREFMEM64;
if (bus->r[reg1].sum < bus->r[reg2].sum) {
// Swap regions so larger area is more likely to align well.
reg1 = PCI_REGION_TYPE_MEM;
@@ -493,6 +535,12 @@ static int pci_bios_init_root_regions(struct pci_bus *bus, u32 start, u32 end)
if (bus->r[reg1].base < start)
// Memory range requested is larger than available.
return -1;
+
+ bus->r[reg3].base = ROOT_BASE(end64, bus->r[reg3].sum, bus->r[reg3].max);
+ if (bus->r[reg3].base < start64)
+ // Memory range requested is larger than available.
+ return -1;
+
return 0;
}
@@ -591,6 +639,9 @@ static void pci_bios_map_devices(struct pci_bus *busses)
if (s->r[PCI_REGION_TYPE_PREFMEM].sum) {
base = s->r[PCI_REGION_TYPE_PREFMEM].base;
limit = base + s->r[PCI_REGION_TYPE_PREFMEM].size - 1;
+ } else if (s->r[PCI_REGION_TYPE_PREFMEM64].sum) {
+ base = s->r[PCI_REGION_TYPE_PREFMEM64].base;
+ limit = base + s->r[PCI_REGION_TYPE_PREFMEM64].size - 1;
} else {
base = PCI_BRIDGE_MEM_MIN;
limit = 0;
@@ -641,11 +692,6 @@ pci_setup(void)
return;
}
- dprintf(3, "pci setup\n");
-
- u32 start = BUILD_PCIMEM_START;
- u32 end = BUILD_PCIMEM_END;
-
dprintf(1, "=== PCI bus & bridge init ===\n");
if (pci_probe_host() != 0) {
return;
@@ -663,7 +709,7 @@ pci_setup(void)
}
memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1));
pci_bios_check_devices(busses);
- if (pci_bios_init_root_regions(&busses[0], start, end) != 0) {
+ if (pci_bios_init_root_regions(&busses[0]) != 0) {
panic("PCI: out of address space\n");
}
--
1.7.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [SeaBIOS] [PATCH v2 1/6] output: add 64bit hex print support
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 1/6] output: add 64bit hex print support Gerd Hoffmann
@ 2012-03-05 15:23 ` Kevin O'Connor
2012-03-06 7:03 ` Gerd Hoffmann
0 siblings, 1 reply; 9+ messages in thread
From: Kevin O'Connor @ 2012-03-05 15:23 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: seabios, qemu-devel
On Wed, Feb 29, 2012 at 12:45:05PM +0100, Gerd Hoffmann wrote:
> ---
> src/output.c | 23 +++++++++++++++++++++--
> 1 files changed, 21 insertions(+), 2 deletions(-)
Thanks Gerd.
I think your patch missed a couple of corner cases. I played with it
a bit and came up with the below.
-Kevin
>From ab16772e7f51e5d9c8e0c44695a76320439d2c78 Mon Sep 17 00:00:00 2001
From: Kevin O'Connor <kevin@koconnor.net>
Date: Mon, 5 Mar 2012 10:14:07 -0500
Subject: [PATCH] output: Add 64bit hex print support.
To: seabios@seabios.org
Based on patch by Gerd Hoffmann <kraxel@redhat.com>.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
---
src/memmap.c | 6 +---
src/output.c | 68 +++++++++++++++++++++++++++++++++++-----------------------
src/post.c | 3 +-
3 files changed, 44 insertions(+), 33 deletions(-)
diff --git a/src/memmap.c b/src/memmap.c
index 20ccae0..bcec34e 100644
--- a/src/memmap.c
+++ b/src/memmap.c
@@ -63,10 +63,8 @@ dump_map(void)
for (i=0; i<e820_count; i++) {
struct e820entry *e = &e820_list[i];
u64 e_end = e->start + e->size;
- dprintf(1, " %d: %08x%08x - %08x%08x = %d %s\n", i
- , (u32)(e->start >> 32), (u32)e->start
- , (u32)(e_end >> 32), (u32)e_end
- , e->type, e820_type_name(e->type));
+ dprintf(1, " %d: %016llx - %016llx = %d %s\n", i
+ , e->start, e_end, e->type, e820_type_name(e->type));
}
}
diff --git a/src/output.c b/src/output.c
index bdde7cc..73d80e9 100644
--- a/src/output.c
+++ b/src/output.c
@@ -194,28 +194,10 @@ putsinglehex(struct putcinfo *action, u32 val)
putc(action, val);
}
-// Output an integer in hexadecimal.
+// Output an integer in hexadecimal with a specified width.
static void
-puthex(struct putcinfo *action, u32 val, int width, int spacepad)
-{
- if (!width) {
- u32 tmp = val;
- width = 1;
- while (tmp >>= 4)
- width++;
- } else if (spacepad) {
- u32 tmp = val;
- u32 count = 1;
- while (tmp >>= 4)
- count++;
- if (width > count) {
- count = width - count;
- width -= count;
- while (count--)
- putc(action, ' ');
- }
- }
-
+puthex(struct putcinfo *action, u32 val, int width)
+{
switch (width) {
default: putsinglehex(action, (val >> 28) & 0xf);
case 7: putsinglehex(action, (val >> 24) & 0xf);
@@ -228,6 +210,20 @@ puthex(struct putcinfo *action, u32 val, int width, int spacepad)
}
}
+// Output an integer in hexadecimal with a minimum width.
+static void
+putprettyhex(struct putcinfo *action, u32 val, int width, int spacepad)
+{
+ u32 tmp = val;
+ int count = 1;
+ while (tmp >>= 4)
+ count++;
+ width -= count;
+ while (width-- > 0)
+ putc(action, spacepad ? ' ' : '0');
+ puthex(action, val, count);
+}
+
static inline int
isdigit(u8 c)
{
@@ -249,6 +245,7 @@ bvprintf(struct putcinfo *action, const char *fmt, va_list args)
const char *n = s+1;
int field_width = 0;
int spacepad = 1;
+ int is64 = 0;
for (;;) {
c = GET_GLOBAL(*(u8*)n);
if (!isdigit(c))
@@ -264,6 +261,11 @@ bvprintf(struct putcinfo *action, const char *fmt, va_list args)
n++;
c = GET_GLOBAL(*(u8*)n);
}
+ if (c == 'l') {
+ is64 = 1;
+ n++;
+ c = GET_GLOBAL(*(u8*)n);
+ }
s32 val;
const char *sarg;
switch (c) {
@@ -272,6 +274,8 @@ bvprintf(struct putcinfo *action, const char *fmt, va_list args)
break;
case 'd':
val = va_arg(args, s32);
+ if (is64)
+ va_arg(args, s32);
if (val < 0) {
putc(action, '-');
val = -val;
@@ -280,17 +284,27 @@ bvprintf(struct putcinfo *action, const char *fmt, va_list args)
break;
case 'u':
val = va_arg(args, s32);
+ if (is64)
+ va_arg(args, s32);
putuint(action, val);
break;
case 'p':
- /* %p always has 0x prepended */
+ val = va_arg(args, s32);
putc(action, '0');
putc(action, 'x');
- field_width = 8;
- spacepad = 0;
+ puthex(action, val, 8);
+ break;
case 'x':
val = va_arg(args, s32);
- puthex(action, val, field_width, spacepad);
+ if (is64) {
+ u32 upper = va_arg(args, s32);
+ if (upper) {
+ putprettyhex(action, upper, field_width - 8, spacepad);
+ puthex(action, val, 8);
+ break;
+ }
+ }
+ putprettyhex(action, val, field_width, spacepad);
break;
case 'c':
val = va_arg(args, int);
@@ -342,7 +356,7 @@ __dprintf(const char *fmt, ...)
if (cur != &MainThread) {
// Show "thread id" for this debug message.
putc_debug(&debuginfo, '|');
- puthex(&debuginfo, (u32)cur, 8, 0);
+ puthex(&debuginfo, (u32)cur, 8);
putc_debug(&debuginfo, '|');
putc_debug(&debuginfo, ' ');
}
@@ -444,12 +458,12 @@ hexdump(const void *d, int len)
while (len > 0) {
if (count % 8 == 0) {
putc(&debuginfo, '\n');
- puthex(&debuginfo, count*4, 8, 0);
+ puthex(&debuginfo, count*4, 8);
putc(&debuginfo, ':');
} else {
putc(&debuginfo, ' ');
}
- puthex(&debuginfo, *(u32*)d, 8, 0);
+ puthex(&debuginfo, *(u32*)d, 8);
count++;
len-=4;
d+=4;
diff --git a/src/post.c b/src/post.c
index b4ad1fa..bd0b530 100644
--- a/src/post.c
+++ b/src/post.c
@@ -150,8 +150,7 @@ ram_probe(void)
add_e820(0xfffbc000, 4*4096, E820_RESERVED);
}
- dprintf(1, "Ram Size=0x%08x (0x%08x%08x high)\n"
- , RamSize, (u32)(RamSizeOver4G >> 32), (u32)RamSizeOver4G);
+ dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G);
}
static void
--
1.7.6.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [SeaBIOS] [PATCH v2 1/6] output: add 64bit hex print support
2012-03-05 15:23 ` [Qemu-devel] [SeaBIOS] " Kevin O'Connor
@ 2012-03-06 7:03 ` Gerd Hoffmann
0 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2012-03-06 7:03 UTC (permalink / raw)
To: Kevin O'Connor; +Cc: seabios, qemu-devel
On 03/05/12 16:23, Kevin O'Connor wrote:
> On Wed, Feb 29, 2012 at 12:45:05PM +0100, Gerd Hoffmann wrote:
>> ---
>> src/output.c | 23 +++++++++++++++++++++--
>> 1 files changed, 21 insertions(+), 2 deletions(-)
>
> Thanks Gerd.
>
> I think your patch missed a couple of corner cases. I played with it
> a bit and came up with the below.
Looks fine.
cheers,
Gerd
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-03-06 7:03 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-02-29 11:45 [Qemu-devel] [PATCH v2 0/6] pci: 64bit support Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 1/6] output: add 64bit hex print support Gerd Hoffmann
2012-03-05 15:23 ` [Qemu-devel] [SeaBIOS] " Kevin O'Connor
2012-03-06 7:03 ` Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 2/6] pci: split device discovery into multiple steps Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 3/6] pci: 64bit support Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 4/6] pci: bridges can have two regions too Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 5/6] pci: fix bridge ressource allocation Gerd Hoffmann
2012-02-29 11:45 ` [Qemu-devel] [PATCH v2 6/6] pci: add prefmem64 Gerd Hoffmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).