Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added new debugging directives
[palacios.git] / palacios / src / devices / nvram.c
1 #include <devices/nvram.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vmm_types.h>
4
5
6 #ifndef DEBUG_NVRAM
7 #undef PrintDebug
8 #define PrintDebug(fmt, args...)
9 #endif
10
11
12
13
14
15 #define NVRAM_REG_PORT  0x70
16 #define NVRAM_DATA_PORT 0x71
17
18
19
20 typedef enum {NVRAM_READY, NVRAM_REG_POSTED} nvram_state_t;
21
22
23 #define NVRAM_REG_MAX   256
24
25
26 // These are borrowed from Bochs, which borrowed from
27 // Ralf Brown's interupt list, and extended
28 #define NVRAM_REG_SEC                     0x00
29 #define NVRAM_REG_SEC_ALARM               0x01
30 #define NVRAM_REG_MIN                     0x02
31 #define NVRAM_REG_MIN_ALARM               0x03
32 #define NVRAM_REG_HOUR                    0x04
33 #define NVRAM_REG_HOUR_ALARM              0x05
34 #define NVRAM_REG_WEEK_DAY                0x06
35 #define NVRAM_REG_MONTH_DAY               0x07
36 #define NVRAM_REG_MONTH                   0x08
37 #define NVRAM_REG_YEAR                    0x09
38 #define NVRAM_REG_STAT_A                  0x0a
39 #define NVRAM_REG_STAT_B                  0x0b
40 #define NVRAM_REG_STAT_C                  0x0c
41 #define NVRAM_REG_STAT_D                  0x0d
42 #define NVRAM_REG_DIAGNOSTIC_STATUS       0x0e  
43 #define NVRAM_REG_SHUTDOWN_STATUS         0x0f
44
45 #define NVRAM_IBM_HD_DATA                 0x12
46
47 #define NVRAM_REG_FLOPPY_TYPE             0x10
48 #define NVRAM_REG_EQUIPMENT_BYTE          0x14
49
50 #define NVRAM_REG_BASE_MEMORY_HIGH        0x16
51 #define NVRAM_REG_BASE_MEMORY_LOW         0x15
52
53 #define NVRAM_REG_EXT_MEMORY_HIGH         0x18
54 #define NVRAM_REG_EXT_MEMORY_LOW          0x17
55
56 #define NVRAM_REG_EXT_MEMORY_2ND_HIGH     0x31
57 #define NVRAM_REG_EXT_MEMORY_2ND_LOW      0x30
58
59 #define NVRAM_REG_BOOTSEQ_OLD             0x2d
60
61 #define NVRAM_REG_AMI_BIG_MEMORY_HIGH     0x35
62 #define NVRAM_REG_AMI_BIG_MEMORY_LOW      0x34
63
64
65 #define NVRAM_REG_CSUM_HIGH               0x2e
66 #define NVRAM_REG_CSUM_LOW                0x2f
67 #define NVRAM_REG_IBM_CENTURY_BYTE        0x32  
68 #define NVRAM_REG_IBM_PS2_CENTURY_BYTE    0x37  
69
70 #define NVRAM_REG_BOOTSEQ_NEW_FIRST       0x3D
71 #define NVRAM_REG_BOOTSEQ_NEW_SECOND      0x38
72
73
74 struct nvram_internal {
75   nvram_state_t dev_state;
76   uchar_t       thereg;
77   uchar_t       mem_state[NVRAM_REG_MAX];
78 };
79
80
81
82 static int set_nvram_defaults(struct vm_device *dev)
83 {
84   struct nvram_internal * nvram_state = (struct nvram_internal*) dev->private_data;
85
86   //
87   // 2 1.44 MB floppy drives
88   //
89 #if 1
90   nvram_state->mem_state[NVRAM_REG_FLOPPY_TYPE]= 0x44;
91 #else
92   nvram_state->mem_state[NVRAM_REG_FLOPPY_TYPE] = 0x00;
93 #endif
94
95   //
96   // For old boot sequence style, do floppy first
97   //
98   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_OLD]= 0x10;
99
100 #if 0
101   // For new boot sequence style, do floppy, cd, then hd
102   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST]= 0x31;
103   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND]= 0x20;
104 #endif
105
106   // For new boot sequence style, do cd, hd, floppy
107   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST]= 0x23;
108   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND]= 0x10;
109  
110
111   // Set equipment byte to note 2 floppies, vga display, keyboard,math,floppy
112   nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE]= 0x4f;
113   //nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE] = 0xf;
114
115   // Set conventional memory to 640K
116   nvram_state->mem_state[NVRAM_REG_BASE_MEMORY_HIGH]= 0x02;
117   nvram_state->mem_state[NVRAM_REG_BASE_MEMORY_LOW]= 0x80;
118
119   // Set extended memory to 15 MB
120   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_HIGH]= 0x3C;
121   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_LOW]= 0x00;
122   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= 0x3C;
123   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= 0x00;
124
125   // Set the extended memory beyond 16 MB to 128-16 MB
126   nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH] = 0x7;
127   nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW] = 0x00;
128
129   //nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH]= 0x00;
130   //nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW]= 0x00;
131
132   
133   // This is the harddisk type.... Set accordingly...
134   nvram_state->mem_state[NVRAM_IBM_HD_DATA] = 0x20;
135
136   // Set the shutdown status gently
137   // soft reset
138   nvram_state->mem_state[NVRAM_REG_SHUTDOWN_STATUS] = 0x0;
139
140
141   // RTC status A
142   // time update in progress, default timebase (32KHz, default interrupt rate 1KHz)
143   // 10100110
144   nvram_state->mem_state[NVRAM_REG_STAT_A] = 0xa6;
145
146   // RTC status B
147   // time updates, default timebase (32KHz, default interrupt rate 1KHz)
148   // 10100110
149   //nvram_state->mem_state[NVRAM_REG_STAT_B] = 0xa6;
150   
151
152
153   return 0;
154
155 }
156
157
158 int nvram_reset_device(struct vm_device * dev)
159 {
160   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
161   
162   PrintDebug("nvram: reset device\n");
163
164  
165
166   data->dev_state = NVRAM_READY;
167   data->thereg=0;
168
169   
170   return 0;
171
172 }
173
174
175
176
177
178 int nvram_start_device(struct vm_device *dev)
179 {
180   PrintDebug("nvram: start device\n");
181   return 0;
182 }
183
184
185 int nvram_stop_device(struct vm_device *dev)
186 {
187   PrintDebug("nvram: stop device\n");
188   return 0;
189 }
190
191
192
193
194 int nvram_write_reg_port(ushort_t port,
195                         void * src, 
196                         uint_t length,
197                         struct vm_device * dev)
198 {
199   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
200
201   memcpy(&(data->thereg), src, 1);
202   PrintDebug("Writing To NVRAM reg: 0x%x\n", data->thereg);
203
204
205   return 1;
206 }
207
208 int nvram_read_data_port(ushort_t port,
209                        void   * dst, 
210                        uint_t length,
211                        struct vm_device * dev)
212 {
213   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
214
215
216
217   memcpy(dst, &(data->mem_state[data->thereg]), 1);
218
219   PrintDebug("nvram_read_data_port(0x%x)=0x%x\n", data->thereg, data->mem_state[data->thereg]);
220
221   // hack
222   if (data->thereg==NVRAM_REG_STAT_A) { 
223     data->mem_state[data->thereg] ^= 0x80;  // toggle Update in progess
224   }
225
226
227   return 1;
228 }
229
230 int nvram_write_data_port(ushort_t port,
231                         void * src, 
232                         uint_t length,
233                         struct vm_device * dev)
234 {
235   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
236
237   memcpy(&(data->mem_state[data->thereg]), src, 1);
238
239   PrintDebug("nvram_write_data_port(0x%x)=0x%x\n", data->thereg, data->mem_state[data->thereg]);
240
241   return 1;
242 }
243
244
245
246 int nvram_init_device(struct vm_device * dev) {
247  
248   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
249
250   PrintDebug("nvram: init_device\n");
251
252   memset(data->mem_state, 0, NVRAM_REG_MAX);
253
254   // Would read state here
255   set_nvram_defaults(dev);
256
257   nvram_reset_device(dev);
258
259   // hook ports
260   dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
261   dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port);
262   
263   return 0;
264 }
265
266 int nvram_deinit_device(struct vm_device *dev)
267 {
268
269
270   dev_unhook_io(dev, NVRAM_REG_PORT);
271   dev_unhook_io(dev, NVRAM_DATA_PORT);
272
273   nvram_reset_device(dev);
274   return 0;
275 }
276
277
278
279
280
281 static struct vm_device_ops dev_ops = { 
282   .init = nvram_init_device, 
283   .deinit = nvram_deinit_device,
284   .reset = nvram_reset_device,
285   .start = nvram_start_device,
286   .stop = nvram_stop_device,
287 };
288
289
290
291
292 struct vm_device *create_nvram() {
293   struct nvram_internal * nvram_state = (struct nvram_internal *)V3_Malloc(sizeof(struct nvram_internal)+1000);
294
295   PrintDebug("internal at %x\n",nvram_state);
296
297   struct vm_device *device = create_device("NVRAM", &dev_ops, nvram_state);
298
299
300   return device;
301 }