@@ -12,6 +12,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
+#include "qemu/units.h"
#include "hw/arm/bcm2835_peripherals.h"
#include "hw/misc/bcm2835_mbox_defs.h"
#include "hw/arm/raspi_platform.h"
@@ -81,6 +82,7 @@ static void bcm2835_peripherals_init(Object *obj)
/* Framebuffer */
object_initialize_child(obj, "fb", &s->fb, TYPE_BCM2835_FB);
object_property_add_alias(obj, "vcram-size", OBJECT(&s->fb), "vcram-size");
+ object_property_add_alias(obj, "vcram-base", OBJECT(&s->fb), "vcram-base");
object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
OBJECT(&s->gpu_bus_mr));
@@ -150,7 +152,7 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
Object *obj;
MemoryRegion *ram;
Error *err = NULL;
- uint64_t ram_size, vcram_size;
+ uint64_t ram_size, vcram_size, vcram_base;
int n;
obj = object_property_get_link(OBJECT(dev), "ram", &error_abort);
@@ -247,15 +249,21 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_ARM_IRQ,
INTERRUPT_ARM_MAILBOX));
- /* Framebuffer */
+ /*
+ * The framebuffer has to live in the first 1gb of addressable
+ * space which is fine for older Pi's with less than 1gb of RAM
+ * but we need to take care not to put it too high otherwise
+ */
vcram_size = object_property_get_uint(OBJECT(s), "vcram-size", &err);
if (err) {
error_propagate(errp, err);
return;
}
+ vcram_base = MIN(ram_size, 1 * GiB) - vcram_size;
+
if (!object_property_set_uint(OBJECT(&s->fb), "vcram-base",
- ram_size - vcram_size, errp)) {
+ vcram_base, errp)) {
return;
}
@@ -62,6 +62,8 @@ static void bcm2836_init(Object *obj)
"board-rev");
object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
"vcram-size");
+ object_property_add_alias(obj, "vcram-base", OBJECT(&s->peripherals),
+ "vcram-base");
}
static bool bcm283x_common_realize(DeviceState *dev, Error **errp)
@@ -196,14 +196,19 @@ static void reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info)
cpu_set_pc(cs, info->smp_loader_start);
}
+/*
+ * NB: ram_limit isn't the same as ram_size - it indicates the portion
+ * of RAM that boot components can live in (up to the first 1gb - the
+ * vcram_size, aka vcram_base)
+ */
static void setup_boot(MachineState *machine, RaspiProcessorId processor_id,
- size_t ram_size)
+ size_t ram_limit)
{
RaspiMachineState *s = RASPI_MACHINE(machine);
int r;
s->binfo.board_id = MACH_TYPE_BCM2708;
- s->binfo.ram_size = ram_size;
+ s->binfo.ram_size = ram_limit;
if (processor_id <= PROCESSOR_ID_BCM2836) {
/*
@@ -238,7 +243,7 @@ static void setup_boot(MachineState *machine, RaspiProcessorId processor_id,
? FIRMWARE_ADDR_2 : FIRMWARE_ADDR_3;
/* load the firmware image (typically kernel.img) */
r = load_image_targphys(machine->firmware, firmware_addr,
- ram_size - firmware_addr);
+ ram_limit - firmware_addr);
if (r < 0) {
error_report("Failed to load firmware from %s", machine->firmware);
exit(1);
@@ -257,7 +262,7 @@ static void raspi_machine_init(MachineState *machine)
RaspiMachineState *s = RASPI_MACHINE(machine);
uint32_t board_rev = mc->board_rev;
uint64_t ram_size = board_ram_size(board_rev);
- uint32_t vcram_size;
+ uint32_t vcram_base;
DriveInfo *di;
BlockBackend *blk;
BusState *bus;
@@ -294,10 +299,10 @@ static void raspi_machine_init(MachineState *machine)
qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
qdev_realize_and_unref(carddev, bus, &error_fatal);
- vcram_size = object_property_get_uint(OBJECT(&s->soc), "vcram-size",
+ vcram_base = object_property_get_uint(OBJECT(&s->soc), "vcram-base",
&error_abort);
- setup_boot(machine, board_processor_id(mc->board_rev),
- machine->ram_size - vcram_size);
+
+ setup_boot(machine, board_processor_id(mc->board_rev), vcram_base);
}
static void raspi_machine_class_common_init(MachineClass *mc,