From: Jan Kiszka <jan.kiszka@web.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RFC][PATCH 2/4] cfi02: Optionally remap chips multiple times
Date: Sun, 13 Apr 2008 12:11:14 +0200 [thread overview]
Message-ID: <4801DC42.8010008@web.de> (raw)
On some boards the flash chip might be mapped several times into the
address space. At least this happens on the MusicPal board (8 MB flash
-> 4 times into a 32 MB window), and the cleanest way I found to deal
with this is extending cfi02 with support for remapping the chip.
Again, if this is considered to be useful for cfi01 as well, I'm willing
to extend the patch.
Signed-off-by: Jan Kiszka <jan.kiszka@web.de>
---
hw/flash.h | 2 +-
hw/pflash_cfi02.c | 50 ++++++++++++++++++++++++++++++++------------------
hw/ppc405_boards.c | 12 ++++++------
3 files changed, 39 insertions(+), 25 deletions(-)
Index: b/hw/flash.h
===================================================================
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -11,7 +11,7 @@ pflash_t *pflash_cfi01_register(target_p
/* pflash_cfi02.c */
pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
BlockDriverState *bs, uint32_t sector_len,
- int nb_blocs, int width,
+ int nb_blocs, int nb_mappings, int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
uint16_t unlock_addr0, uint16_t unlock_addr1);
Index: b/hw/pflash_cfi02.c
===================================================================
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -55,7 +55,8 @@ struct pflash_t {
BlockDriverState *bs;
target_phys_addr_t base;
uint32_t sector_len;
- uint32_t total_len;
+ uint32_t chip_len;
+ int mappings;
int width;
int wcycle; /* if 0, the flash is read normally */
int bypass;
@@ -72,6 +73,19 @@ struct pflash_t {
void *storage;
};
+static void pflash_register_memory(pflash_t *pfl, int rom_mode)
+{
+ unsigned long phys_offset = pfl->fl_mem;
+ int i;
+
+ if (rom_mode)
+ phys_offset |= pfl->off | IO_MEM_ROMD;
+
+ for (i = 0; i < pfl->mappings; i++)
+ cpu_register_physical_memory(pfl->base + i * pfl->chip_len,
+ pfl->chip_len, phys_offset);
+}
+
static void pflash_timer (void *opaque)
{
pflash_t *pfl = opaque;
@@ -82,8 +96,7 @@ static void pflash_timer (void *opaque)
if (pfl->bypass) {
pfl->wcycle = 2;
} else {
- cpu_register_physical_memory(pfl->base, pfl->total_len,
- pfl->off | IO_MEM_ROMD | pfl->fl_mem);
+ pflash_register_memory(pfl, 1);
pfl->wcycle = 0;
}
pfl->cmd = 0;
@@ -98,6 +111,7 @@ static uint32_t pflash_read (pflash_t *p
DPRINTF("%s: offset " TARGET_FMT_lx "\n", __func__, offset);
ret = -1;
offset -= pfl->base;
+ offset &= pfl->chip_len - 1;
boff = offset & 0xFF;
if (pfl->width == 2)
boff = boff >> 1;
@@ -226,11 +240,10 @@ static void pflash_write (pflash_t *pfl,
offset -= (uint32_t)(long)pfl->storage;
else
offset -= pfl->base;
+ offset &= pfl->chip_len - 1;
DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d\n", __func__,
offset, value, width);
- /* Set the device in I/O access mode */
- cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
boff = offset & (pfl->sector_len - 1);
if (pfl->width == 2)
boff = boff >> 1;
@@ -238,6 +251,8 @@ static void pflash_write (pflash_t *pfl,
boff = boff >> 2;
switch (pfl->wcycle) {
case 0:
+ /* Set the device in I/O access mode */
+ pflash_register_memory(pfl, 0);
/* We're in read mode */
check_unlock0:
if (boff == 0x55 && cmd == 0x98) {
@@ -369,9 +384,9 @@ static void pflash_write (pflash_t *pfl,
}
/* Chip erase */
DPRINTF("%s: start chip erase\n", __func__);
- memset(pfl->storage, 0xFF, pfl->total_len);
+ memset(pfl->storage, 0xFF, pfl->chip_len);
pfl->status = 0x00;
- pflash_update(pfl, 0, pfl->total_len);
+ pflash_update(pfl, 0, pfl->chip_len);
/* Let's wait 5 seconds before chip erase is done */
qemu_mod_timer(pfl->timer,
qemu_get_clock(vm_clock) + (ticks_per_sec * 5));
@@ -424,8 +439,7 @@ static void pflash_write (pflash_t *pfl,
/* Reset flash */
reset_flash:
- cpu_register_physical_memory(pfl->base, pfl->total_len,
- pfl->off | IO_MEM_ROMD | pfl->fl_mem);
+ pflash_register_memory(pfl, 1);
pfl->bypass = 0;
pfl->wcycle = 0;
pfl->cmd = 0;
@@ -527,15 +541,15 @@ static int ctz32 (uint32_t n)
pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
BlockDriverState *bs, uint32_t sector_len,
- int nb_blocs, int width,
+ int nb_blocs, int nb_mappings, int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
uint16_t unlock_addr0, uint16_t unlock_addr1)
{
pflash_t *pfl;
- int32_t total_len;
+ int32_t chip_len;
- total_len = sector_len * nb_blocs;
+ chip_len = sector_len * nb_blocs;
/* XXX: to be fixed */
#if 0
if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
@@ -549,12 +563,14 @@ pflash_t *pflash_cfi02_register(target_p
pfl->fl_mem = cpu_register_io_memory(0, pflash_read_ops, pflash_write_ops,
pfl);
pfl->off = off;
- cpu_register_physical_memory(base, total_len,
- off | pfl->fl_mem | IO_MEM_ROMD);
+ pfl->base = base;
+ pfl->chip_len = chip_len;
+ pfl->mappings = nb_mappings;
+ pflash_register_memory(pfl, 1);
pfl->bs = bs;
if (pfl->bs) {
/* read the initial flash content */
- bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
+ bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
}
#if 0 /* XXX: there should be a bit to set up read-only,
* the same way the hardware does (with WP pin).
@@ -564,9 +580,7 @@ pflash_t *pflash_cfi02_register(target_p
pfl->ro = 0;
#endif
pfl->timer = qemu_new_timer(vm_clock, pflash_timer, pfl);
- pfl->base = base;
pfl->sector_len = sector_len;
- pfl->total_len = total_len;
pfl->width = width;
pfl->wcycle = 0;
pfl->cmd = 0;
@@ -620,7 +634,7 @@ pflash_t *pflash_cfi02_register(target_p
/* Max timeout for chip erase */
pfl->cfi_table[0x26] = 0x0D;
/* Device size */
- pfl->cfi_table[0x27] = ctz32(total_len) + 1;
+ pfl->cfi_table[0x27] = ctz32(chip_len) + 1;
/* Flash device interface (8 & 16 bits) */
pfl->cfi_table[0x28] = 0x02;
pfl->cfi_table[0x29] = 0x00;
Index: b/hw/ppc405_boards.c
===================================================================
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -235,8 +235,8 @@ static void ref405ep_init (int ram_size,
bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
#endif
pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
- drives_table[index].bdrv, 65536, fl_sectors, 2,
- 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+ drives_table[index].bdrv, 65536, fl_sectors, 1,
+ 2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
fl_idx++;
} else
#endif
@@ -552,8 +552,8 @@ static void taihu_405ep_init(int ram_siz
bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
#endif
pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
- drives_table[index].bdrv, 65536, fl_sectors, 4,
- 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+ drives_table[index].bdrv, 65536, fl_sectors, 1,
+ 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
fl_idx++;
} else
#endif
@@ -588,8 +588,8 @@ static void taihu_405ep_init(int ram_siz
bdrv_get_device_name(drives_table[index].bdrv));
#endif
pflash_cfi02_register(0xfc000000, bios_offset,
- drives_table[index].bdrv, 65536, fl_sectors, 4,
- 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+ drives_table[index].bdrv, 65536, fl_sectors, 1,
+ 4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
fl_idx++;
}
/* Register CLPD & LCD display */
reply other threads:[~2008-04-13 10:11 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4801DC42.8010008@web.de \
--to=jan.kiszka@web.de \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).