From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=35230 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OwIDL-00018M-A8 for qemu-devel@nongnu.org; Thu, 16 Sep 2010 13:25:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OwI84-0003Pj-FM for qemu-devel@nongnu.org; Thu, 16 Sep 2010 13:20:13 -0400 Received: from mail-vw0-f45.google.com ([209.85.212.45]:59930) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OwI84-0003PX-D6 for qemu-devel@nongnu.org; Thu, 16 Sep 2010 13:20:12 -0400 Received: by vws19 with SMTP id 19so1161696vws.4 for ; Thu, 16 Sep 2010 10:20:11 -0700 (PDT) Message-ID: <4C9251C6.2090705@codemonkey.ws> Date: Thu, 16 Sep 2010 12:20:06 -0500 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH] CMOS file support References: <1284645517-32743-1-git-send-email-mathias.krause@secunet.com> In-Reply-To: <1284645517-32743-1-git-send-email-mathias.krause@secunet.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Mathias Krause Cc: qemu-devel@nongnu.org On 09/16/2010 08:58 AM, Mathias Krause wrote: > 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 > Instead of using FILE, I'd suggest using a BlockDriver to read and write the data. I think it would be very nice to add write support too so that writes to CMOS were persisted across boots. > --- > 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; > +} > BlockDrivers have a getlength() functions. Regards, Anthony Liguori