DevEEPROM.h revision c5243c2aba3562de938f9488c7704500e6b0fb98
/* $Id$ */
/** @file
* DevEEPROM - Microware-compatible 64x16-bit 93C46 EEPROM Emulation, Header.
*/
/*
* Copyright (C) 2007-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* you can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
/* Interface */
#include <iprt/types.h>
/** The current Saved state version. */
#define EEPROM93C46_SAVEDSTATE_VERSION 1
/**
* 93C46-compatible EEPROM device emulation.
*
* @remarks This class is intended to be used in device
* emulation which imposes some restrictions if the
* device supports GC execution. This is why it is a
* plain-old-data structure.
*/
struct EEPROM93C46
{
/** General definitions */
enum {
/** Size of EEPROM in words */
SIZE = 64,
/** Number of bits per word */
WORD_SIZE = 16,
/** Number of address bits */
ADDR_SIZE = 6,
/** Number of bits in opcode */
OPCODE_SIZE = 2,
/** The most significant bit mask in data word */
DATA_MSB = 1<<(WORD_SIZE-1),
/** Address mask */
ADDR_MASK = (1<<ADDR_SIZE)-1,
/** The most significant bit mask in op+addr bit sequence */
OPADDR_MSB = 1<<(OPCODE_SIZE+ADDR_SIZE-1)
};
enum OP {
OP_READ,
OP_WRITE,
OP_WRITE_ALL,
OP_DECODE,
OP_32BIT_HACK = 0x7fffffff
};
/**
* Names of signal wires
*/
enum Wires {
WIRES_SK=0x1, ///< Clock
WIRES_CS=0x2, ///< Chip Select
WIRES_DI=0x4, ///< Data In
WIRES_DO=0x8 ///< Data Out
};
/** @todo save and load methods */
void save(PSSMHANDLE pSSM);
int load(PSSMHANDLE pSSM);
/** Actual content of EEPROM */
uint16_t m_au16Data[SIZE];
/** current state.
*
* EEPROM operates as a simple state machine. Events are primarily
* triggered at positive edge of clock signal (SK). Refer to the
* timing diagrams of 93C46 to get better understanding.
*/
enum State {
/** Initial state. Waiting for start condition (CS, SK, DI high). */
STANDBY,
/** Reading data in, shifting in the bits into 'word'. */
READING_DI,
/** Writing data out, shifting out the bits from 'word'. */
WRITING_DO,
/** Waiting for CS=0 to indicate we are busy (DO=0). */
WAITING_CS_FALL,
/** Waiting for CS=1 to indicate we are ready (DO=1). */
WAITING_CS_RISE,
/** Make this enum 4-byte */
STATE_MAKE_32BIT_HACK = 0x7fffffff
} m_eState;
/** setting writeEnable to false prevents write and erase operations */
bool m_fWriteEnabled;
uint8_t Alignment1;
/** intermediate storage */
uint16_t m_u16Word;
/** currently processed bit in 'word' */
uint16_t m_u16Mask;
/** decoded address */
uint16_t m_u16Addr;
/** Data Out, Data In, Chip Select, Clock */
uint32_t m_u32InternalWires;
/** Current opcode decoder. When no operation has been decoded yet
* it is set to OP_DECODE.
*/
OP m_eOp;
#if HC_ARCH_BITS == 64
uint32_t Alignment2;
#endif
#ifdef IN_RING3
uint32_t read();
void write(uint32_t u32Wires);
bool readWord(uint32_t u32Addr, uint16_t *pu16Value);
void init(const uint16_t *pu16Initial = 0);
// Operation handlers
State opDecode();
State opRead();
State opWrite();
State opWriteAll();
/** Helper method to implement write protection */
void storeWord(uint32_t u32Addr, uint16_t u16Value);
#endif /* IN_RING3 */
};