1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
/* $Id: DevEEPROM.h $ */
/** @file
* DevEEPROM - Microwire-compatible 64x16-bit 93C46 EEPROM Emulation, Header.
*/
/*
* Copyright (C) 2007-2019 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.
*/
#ifndef VBOX_INCLUDED_SRC_Network_DevEEPROM_h
#define VBOX_INCLUDED_SRC_Network_DevEEPROM_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif
#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 */
};
#endif /* !VBOX_INCLUDED_SRC_Network_DevEEPROM_h */
|