VirtualBox

source: vbox/trunk/src/VBox/Devices/Network/DevEEPROM.cpp@ 20958

Last change on this file since 20958 was 15955, checked in by vboxsync, 16 years ago

fix OSE headers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/* $Id: DevEEPROM.cpp 15955 2009-01-14 20:14:36Z vboxsync $ */
2/** @file
3 * DevEEPROM - Microware-compatible 64x16-bit 93C46 EEPROM Emulation.
4 */
5
6/*
7 * Copyright (C) 2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#define LOG_GROUP LOG_GROUP_DEV_E1000 /// @todo Add a EEPROM logging group.
23#include <VBox/log.h>
24#include <iprt/string.h>
25#include "DevEEPROM.h"
26
27#define E1kLog(a) Log(a)
28
29/**
30 * Initialize EEPROM device.
31 *
32 * @param pu16Initial Initial EEPROM content (optional). The size of initial
33 * content must be sizeof(uint16_t)*EEPROM93C46::SIZE
34 * bytes.
35 */
36void EEPROM93C46::init(const uint16_t *pu16Initial)
37{
38 if ( pu16Initial ) {
39 memcpy(this->m_au16Data, pu16Initial, sizeof(this->m_au16Data));
40 } else {
41 memset(this->m_au16Data, 0, sizeof(this->m_au16Data));
42 }
43 m_fWriteEnabled = false;
44 m_u32InternalWires = 0;
45 m_eState = STANDBY;
46}
47
48/**
49 * Writes one word to specified location if write is enabled.
50 *
51 * @param u32Addr Address to write at
52 * @param u16Value Value to store
53 */
54void EEPROM93C46::storeWord(uint32_t u32Addr, uint16_t u16Value)
55{
56 if (m_fWriteEnabled) {
57 E1kLog(("EEPROM: Stored word %04x at %08x\n", u16Value, u32Addr));
58 m_au16Data[u32Addr] = u16Value;
59 }
60 m_u16Mask = DATA_MSB;
61}
62
63/**
64 * Fetch next word pointer by m_u16Addr.
65 *
66 * m_u16Addr is advanced and mask is reset to support sequential reads.
67 *
68 * @returns New state
69 */
70EEPROM93C46::State EEPROM93C46::opRead()
71{
72 m_u16Word = m_au16Data[m_u16Addr++];
73 E1kLog(("EEPROM: Reading word %04x at %08x\n", m_u16Word, m_u16Addr-1));
74 m_u16Mask = DATA_MSB;
75 return WRITING_DO;
76}
77
78/**
79 * Write the value of m_u16Word to the location specified by m_u16Addr.
80 *
81 * @returns New state
82 *
83 * @remarks Need to wait for CS lower/raise to show busy/ready indication.
84 */
85EEPROM93C46::State EEPROM93C46::opWrite()
86{
87 storeWord(m_u16Addr, m_u16Word);
88 return WAITING_CS_FALL;
89}
90
91/**
92 * Overwrite the entire contents of EEPROM with the value of m_u16Word.
93 *
94 * @returns New state
95 *
96 * @remarks Need to wait for CS lower/raise to show busy/ready indication.
97 */
98EEPROM93C46::State EEPROM93C46::opWriteAll()
99{
100 for (int i = 0; i < SIZE; i++)
101 storeWord(i, m_u16Word);
102 return WAITING_CS_FALL;
103}
104
105/**
106 * Decode opcode and address from 'opAddr' member.
107 *
108 * Decodes operation and executes it immediately if possible; otherwise, stores
109 * the decoded operation and address.
110 *
111 * @returns New state
112 */
113EEPROM93C46::State EEPROM93C46::opDecode()
114{
115 switch (m_u16Word>>6) {
116 case 3: /* ERASE */
117 storeWord(m_u16Word & ADDR_MASK, 0xFFFF);
118 return WAITING_CS_FALL;
119 case 2: /* READ */
120 m_eOp = OP_READ;
121 m_u16Addr = m_u16Word & ADDR_MASK;
122 return opRead(); /* Load first word */
123 case 1: /* WRITE */
124 m_eOp = OP_WRITE;
125 m_u16Addr = m_u16Word & ADDR_MASK;
126 m_u16Word = 0;
127 m_u16Mask = DATA_MSB;
128 return READING_DI;
129 case 0:
130 switch (m_u16Word>>4) {
131 case 0: /* ERASE/WRITE DISABLE */
132 m_fWriteEnabled = false;
133 return STANDBY;
134 case 1: /* WRITE ALL */
135 m_eOp = OP_WRITE_ALL;
136 m_u16Word = 0;
137 m_u16Mask = DATA_MSB;
138 return READING_DI;
139 case 2: /* ERASE ALL */
140 /* Re-use opWriteAll */
141 m_u16Word = 0xFFFF;
142 return opWriteAll();
143 case 3: /* ERASE/WRITE ENABLE */
144 m_fWriteEnabled = true;
145 return STANDBY;
146 }
147 }
148 return m_eState;
149}
150
151/**
152 * Set bits in EEPROM 4-wire interface.
153 *
154 * @param u32Wires Values of DI, CS, SK.
155 * @remarks The value of DO bit in 'u32Wires' is ignored.
156 */
157void EEPROM93C46::write(uint32_t u32Wires)
158{
159 if (u32Wires & WIRES_CS) {
160 if (!(m_u32InternalWires & WIRES_SK) && (u32Wires & WIRES_SK)) {
161 /* Positive edge of clock */
162 if (m_eState == STANDBY) {
163 if (u32Wires & WIRES_DI) {
164 m_eState = READING_DI;
165 m_eOp = OP_DECODE;
166 m_u16Mask = OPADDR_MSB;
167 m_u16Word = 0;
168 }
169 }
170 else {
171 if (m_eState == READING_DI) {
172 if (u32Wires & WIRES_DI) {
173 m_u16Word |= m_u16Mask;
174 }
175 }
176 else if (m_eState == WRITING_DO) {
177 m_u32InternalWires &= ~WIRES_DO;
178 if (m_u16Word & m_u16Mask) {
179 m_u32InternalWires |= WIRES_DO;
180 }
181 }
182 else return;
183 /* Next bit */
184 m_u16Mask >>= 1;
185 if (m_u16Mask == 0)
186 {
187 switch (this->m_eOp)
188 {
189 case OP_READ:
190 m_eState = opRead();
191 break;
192 case OP_WRITE:
193 m_eState = opWrite();
194 break;
195 case OP_WRITE_ALL:
196 m_eState = opWriteAll();
197 break;
198 case OP_DECODE:
199 m_eState = opDecode();
200 break;
201 default:
202 ;
203 }
204 }
205 }
206 }
207 else if (m_eState == WAITING_CS_RISE) {
208 m_u32InternalWires |= WIRES_DO; /* ready */
209 m_eState = STANDBY;
210 }
211 }
212 else {
213 switch(m_eState) {
214 case WAITING_CS_FALL:
215 m_eState = WAITING_CS_RISE;
216 m_u32InternalWires &= ~WIRES_DO; /* busy */
217 break;
218 case WAITING_CS_RISE:
219 break;
220 case READING_DI:
221 m_u32InternalWires &= ~WIRES_DO; /* Clear ready/busy status from DO. */
222 /* Fall through! */
223 default:
224 m_eState = STANDBY;
225 break;
226 }
227 }
228 m_u32InternalWires &= WIRES_DO;
229 m_u32InternalWires |= u32Wires & ~WIRES_DO; /* Do not overwrite DO */
230}
231
232/**
233 * Read bits in EEPROM 4-wire interface.
234 *
235 * @returns Current values of DO, DI, CS, SK.
236 *
237 * @remarks Only DO is controlled by EEPROM, other bits are returned as they
238 * were written by 'write'.
239 */
240uint32_t EEPROM93C46::read()
241{
242 return m_u32InternalWires;
243}
244
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette