[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] CMOS file support
From: |
Mathias Krause |
Subject: |
[Qemu-devel] [PATCH] CMOS file support |
Date: |
Thu, 16 Sep 2010 15:58:37 +0200 |
In contrast to the BIOS and Option ROMs the CMOS content cannot be
predefined by the user. Also the amount of useable CMOS ARM is pretty
limited, even though the amount of CMOS bytes emulated by qemu is
already twice as much as of the original MC146818. Nevertheless those
limitations are pretty annoying when testing different BIOS replacement
implementations like coreboot in combination with FILO that use CMOS
values above the basic RTC range for its own purpose to, e.g., control
the boot device order using a string containing the boot devices to
probe.
This patch adds support to specify a file to read the initial CMOS
content from. It also increases the CMOS size to 256 bytes and
implements access to the extended memory range via I/O ports 0x72 and
0x73.
Use it like: `qemu -global mc146818rtc.file=cmos.bin ...' where cmos.bin
is a binary file, sized 256 bytes containing the CMOS RAM.
Signed-off-by: Mathias Krause <address@hidden>
---
hw/mc146818rtc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 2b91fa8..9f215e0 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -78,12 +78,16 @@
#define REG_C_PF 0x40
#define REG_C_AF 0x20
+#define BASE_PORT 0x70
+#define CMOS_SIZE 256
+
typedef struct RTCState {
ISADevice dev;
- uint8_t cmos_data[128];
+ uint8_t cmos_data[CMOS_SIZE];
uint8_t cmos_index;
struct tm current_tm;
int32_t base_year;
+ char *file;
qemu_irq irq;
qemu_irq sqw_irq;
int it_shift;
@@ -206,7 +210,7 @@ static void cmos_ioport_write(void *opaque, uint32_t addr,
uint32_t data)
RTCState *s = opaque;
if ((addr & 1) == 0) {
- s->cmos_index = data & 0x7f;
+ s->cmos_index = data & (addr == BASE_PORT ? 0x7f : 0xff);
} else {
CMOS_DPRINTF("cmos: write index=0x%02x val=0x%02x\n",
s->cmos_index, data);
@@ -581,7 +585,6 @@ static void rtc_reset(void *opaque)
static int rtc_initfn(ISADevice *dev)
{
RTCState *s = DO_UPCAST(RTCState, dev, dev);
- int base = 0x70;
s->cmos_data[RTC_REG_A] = 0x26;
s->cmos_data[RTC_REG_B] = 0x02;
@@ -603,14 +606,57 @@ static int rtc_initfn(ISADevice *dev)
qemu_get_clock(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
qemu_mod_timer(s->second_timer2, s->next_second_time);
- register_ioport_write(base, 2, 1, cmos_ioport_write, s);
- register_ioport_read(base, 2, 1, cmos_ioport_read, s);
+ register_ioport_write(BASE_PORT, 4, 1, cmos_ioport_write, s);
+ register_ioport_read(BASE_PORT, 4, 1, cmos_ioport_read, s);
- qdev_set_legacy_instance_id(&dev->qdev, base, 2);
+ qdev_set_legacy_instance_id(&dev->qdev, BASE_PORT, 2);
qemu_register_reset(rtc_reset, s);
return 0;
}
+static long get_file_size(FILE *f)
+{
+ long where, size;
+
+ /* XXX: on Unix systems, using fstat() probably makes more sense */
+
+ where = ftell(f);
+ fseek(f, 0, SEEK_END);
+ size = ftell(f);
+ fseek(f, where, SEEK_SET);
+
+ return size;
+}
+
+static void cmos_load_from_file(RTCState *s, const char *file)
+{
+ const char *err_msg = NULL;
+ FILE *f;
+
+ if (!(f = fopen(file, "r"))) {
+ err_msg = strerror(errno);
+ goto err;
+ }
+
+ if (get_file_size(f) != CMOS_SIZE) {
+ err_msg = "invalid file size";
+ goto err;
+ }
+
+ if (fread(s->cmos_data, 1, CMOS_SIZE, f) != CMOS_SIZE) {
+ err_msg = strerror(errno);
+ goto err;
+ }
+ CMOS_DPRINTF("cmos: initialized from '%s'\n", file);
+
+ fclose(f);
+
+ return;
+err:
+ fprintf(stderr, "qemu: could not load CMOS '%s': %s\n", file, err_msg);
+ exit(1);
+}
+
ISADevice *rtc_init(int base_year, qemu_irq intercept_irq)
{
ISADevice *dev;
@@ -618,6 +664,9 @@ ISADevice *rtc_init(int base_year, qemu_irq intercept_irq)
dev = isa_create("mc146818rtc");
s = DO_UPCAST(RTCState, dev, dev);
+ if (s->file != NULL) {
+ cmos_load_from_file(s, s->file);
+ }
qdev_prop_set_int32(&dev->qdev, "base_year", base_year);
qdev_init_nofail(&dev->qdev);
if (intercept_irq) {
@@ -636,6 +685,7 @@ static ISADeviceInfo mc146818rtc_info = {
.init = rtc_initfn,
.qdev.props = (Property[]) {
DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
+ DEFINE_PROP_STRING("file", RTCState, file),
DEFINE_PROP_END_OF_LIST(),
}
};
--
1.5.6.5
- [Qemu-devel] [PATCH] CMOS file support,
Mathias Krause <=
Re: [Qemu-devel] [PATCH] CMOS file support, Anthony Liguori, 2010/09/16