* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
//#define PFLASH_DEBUG
#ifdef PFLASH_DEBUG
-#define DPRINTF(fmt, args...) \
+#define DPRINTF(fmt, ...) \
do { \
- printf("PFLASH: " fmt , ##args); \
+ printf("PFLASH: " fmt , ## __VA_ARGS__); \
} while (0)
#else
-#define DPRINTF(fmt, args...) do { } while (0)
+#define DPRINTF(fmt, ...) do { } while (0)
#endif
struct pflash_t {
DPRINTF("%s: offset " TARGET_FMT_lx "\n", __func__, offset);
ret = -1;
if (pfl->rom_mode) {
- offset -= (uint32_t)(long)pfl->storage;
/* Lazy reset of to ROMD mode */
if (pfl->wcycle == 0)
pflash_register_memory(pfl, 1);
- } else
- offset -= pfl->base;
+ }
offset &= pfl->chip_len - 1;
boff = offset & 0xFF;
if (pfl->width == 2)
}
DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d %d\n", __func__,
offset, value, width, pfl->wcycle);
- /* WARNING: when the memory area is in ROMD mode, the offset is a
- ram offset, not a physical address */
- if (pfl->rom_mode)
- 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__,
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));
+ qemu_get_clock(vm_clock) + (get_ticks_per_sec() * 5));
break;
case 0x30:
/* Sector erase */
pfl->status = 0x00;
/* Let's wait 1/2 second before sector erase is done */
qemu_mod_timer(pfl->timer,
- qemu_get_clock(vm_clock) + (ticks_per_sec / 2));
+ qemu_get_clock(vm_clock) + (get_ticks_per_sec() / 2));
break;
default:
DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);
pflash_write(pfl, addr, value, 4);
}
-static CPUWriteMemoryFunc *pflash_write_ops[] = {
+static CPUWriteMemoryFunc * const pflash_write_ops[] = {
&pflash_writeb,
&pflash_writew,
&pflash_writel,
};
-static CPUReadMemoryFunc *pflash_read_ops[] = {
+static CPUReadMemoryFunc * const pflash_read_ops[] = {
&pflash_readb,
&pflash_readw,
&pflash_readl,
{
pflash_t *pfl;
int32_t chip_len;
+ int ret;
chip_len = sector_len * nb_blocs;
/* XXX: to be fixed */
return NULL;
#endif
pfl = qemu_mallocz(sizeof(pflash_t));
- if (pfl == NULL)
- return NULL;
- pfl->storage = phys_ram_base + off;
- pfl->fl_mem = cpu_register_io_memory(0, pflash_read_ops, pflash_write_ops,
+ /* FIXME: Allocate ram ourselves. */
+ pfl->storage = qemu_get_ram_ptr(off);
+ pfl->fl_mem = cpu_register_io_memory(pflash_read_ops, pflash_write_ops,
pfl);
pfl->off = off;
pfl->base = base;
pfl->bs = bs;
if (pfl->bs) {
/* read the initial flash content */
- bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
+ ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
+ if (ret < 0) {
+ cpu_unregister_io_memory(pfl->fl_mem);
+ qemu_free(pfl);
+ return NULL;
+ }
}
#if 0 /* XXX: there should be a bit to set up read-only,
* the same way the hardware does (with WP pin).
/* Command set (AMD/Fujitsu) */
pfl->cfi_table[0x13] = 0x02;
pfl->cfi_table[0x14] = 0x00;
- /* Primary extended table address (none) */
- pfl->cfi_table[0x15] = 0x00;
+ /* Primary extended table address */
+ pfl->cfi_table[0x15] = 0x31;
pfl->cfi_table[0x16] = 0x00;
/* Alternate command set (none) */
pfl->cfi_table[0x17] = 0x00;
pfl->cfi_table[0x1E] = 0x00;
/* Reserved */
pfl->cfi_table[0x1F] = 0x07;
- /* Timeout for min size buffer write (16 µs) */
- pfl->cfi_table[0x20] = 0x04;
+ /* Timeout for min size buffer write (NA) */
+ pfl->cfi_table[0x20] = 0x00;
/* Typical timeout for block erase (512 ms) */
pfl->cfi_table[0x21] = 0x09;
/* Typical timeout for full chip erase (4096 ms) */
pfl->cfi_table[0x22] = 0x0C;
/* Reserved */
pfl->cfi_table[0x23] = 0x01;
- /* Max timeout for buffer write */
- pfl->cfi_table[0x24] = 0x04;
+ /* Max timeout for buffer write (NA) */
+ pfl->cfi_table[0x24] = 0x00;
/* Max timeout for block erase */
pfl->cfi_table[0x25] = 0x0A;
/* Max timeout for chip erase */
pfl->cfi_table[0x26] = 0x0D;
/* Device size */
- pfl->cfi_table[0x27] = ctz32(chip_len) + 1;
+ pfl->cfi_table[0x27] = ctz32(chip_len);
/* Flash device interface (8 & 16 bits) */
pfl->cfi_table[0x28] = 0x02;
pfl->cfi_table[0x29] = 0x00;
pfl->cfi_table[0x2F] = sector_len >> 8;
pfl->cfi_table[0x30] = sector_len >> 16;
+ /* Extended */
+ pfl->cfi_table[0x31] = 'P';
+ pfl->cfi_table[0x32] = 'R';
+ pfl->cfi_table[0x33] = 'I';
+
+ pfl->cfi_table[0x34] = '1';
+ pfl->cfi_table[0x35] = '0';
+
+ pfl->cfi_table[0x36] = 0x00;
+ pfl->cfi_table[0x37] = 0x00;
+ pfl->cfi_table[0x38] = 0x00;
+ pfl->cfi_table[0x39] = 0x00;
+
+ pfl->cfi_table[0x3a] = 0x00;
+
+ pfl->cfi_table[0x3b] = 0x00;
+ pfl->cfi_table[0x3c] = 0x00;
+
return pfl;
}