VirtualBox

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

最後變更 在這個檔案從15953是 15953,由 vboxsync 提交於 16 年 前

export E1000 to OSE

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

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