summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Network/DevEEPROM.h
blob: 943dc70d975cbadf4815f95bfa795607ff11f9f2 (plain)
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
142
143
144
145
146
147
148
149
150
151
/* $Id: DevEEPROM.h $ */
/** @file
 * DevEEPROM - Microwire-compatible 64x16-bit 93C46 EEPROM Emulation, Header.
 */

/*
 * Copyright (C) 2007-2023 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * SPDX-License-Identifier: GPL-3.0-only
 */

#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(PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM);
    int  load(PCPDMDEVHLPR3 pHlp, 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 */