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.


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