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.


Working odin - x86 only - do 0 and then F5 to avoid startup files
[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 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
108   // Set conventional memory to 640K
109   nvram_state->mem_state[NVRAM_REG_BASE_MEMORY_HIGH]= 0x02;
110   nvram_state->mem_state[NVRAM_REG_BASE_MEMORY_LOW]= 0x80;
111
112   // Set extended memory to 15 MB
113   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_HIGH]= 0x3C;
114   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_LOW]= 0x00;
115   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= 0x3C;
116   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= 0x00;
117
118   // Set the extended memory beyond 16 MB to 128-16 MB
119   // nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH]= 0x7;
120   //nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW]= 0x00;
121
122   nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH]= 0x00;
123   nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW]= 0x00;
124
125   
126   // This is the harddisk type.... Set accordingly...
127   nvram_state->mem_state[NVRAM_IBM_HD_DATA] = 0x20;
128
129   return 0;
130
131 }
132
133
134 int nvram_reset_device(struct vm_device * dev)
135 {
136   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
137   
138   SerialPrint("nvram: reset device\n");
139
140  
141
142   data->dev_state = NVRAM_READY;
143   data->thereg=0;
144
145   
146   return 0;
147
148 }
149
150
151
152
153
154 int nvram_start_device(struct vm_device *dev)
155 {
156   SerialPrint("nvram: start device\n");
157   return 0;
158 }
159
160
161 int nvram_stop_device(struct vm_device *dev)
162 {
163   SerialPrint("nvram: stop device\n");
164   return 0;
165 }
166
167
168
169
170 int nvram_write_reg_port(ushort_t port,
171                         void * src, 
172                         uint_t length,
173                         struct vm_device * dev)
174 {
175   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
176
177   memcpy(&(data->thereg), src, 1);
178   PrintDebug("Writing To NVRAM reg: 0x%x\n", data->thereg);
179
180
181   return 1;
182 }
183
184 int nvram_read_data_port(ushort_t port,
185                        void   * dst, 
186                        uint_t length,
187                        struct vm_device * dev)
188 {
189   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
190
191
192
193   memcpy(dst, &(data->mem_state[data->thereg]), 1);
194
195   PrintDebug("nvram_read_data_port(0x%x)=0x%x\n", data->thereg, data->mem_state[data->thereg]);
196
197   return 1;
198 }
199
200 int nvram_write_data_port(ushort_t port,
201                         void * src, 
202                         uint_t length,
203                         struct vm_device * dev)
204 {
205   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
206
207   memcpy(&(data->mem_state[data->thereg]), src, 1);
208
209   PrintDebug("nvram_write_data_port(0x%x)=0x%x\n", data->thereg, data->mem_state[data->thereg]);
210
211   return 1;
212 }
213
214
215
216 int nvram_init_device(struct vm_device * dev) {
217  
218   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
219
220   SerialPrint("nvram: init_device\n");
221
222   memset(data->mem_state, 0, NVRAM_REG_MAX);
223
224   // Would read state here
225   set_nvram_defaults(dev);
226
227   nvram_reset_device(dev);
228
229   // hook ports
230   dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
231   dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port);
232   
233   return 0;
234 }
235
236 int nvram_deinit_device(struct vm_device *dev)
237 {
238
239
240   dev_unhook_io(dev, NVRAM_REG_PORT);
241   dev_unhook_io(dev, NVRAM_DATA_PORT);
242
243   nvram_reset_device(dev);
244   return 0;
245 }
246
247
248
249
250
251 static struct vm_device_ops dev_ops = { 
252   .init = nvram_init_device, 
253   .deinit = nvram_deinit_device,
254   .reset = nvram_reset_device,
255   .start = nvram_start_device,
256   .stop = nvram_stop_device,
257 };
258
259
260
261
262 struct vm_device *create_nvram() {
263   struct nvram_internal * nvram_state = os_hooks->malloc(sizeof(struct nvram_internal)+1000);
264
265   SerialPrint("internal at %x\n",nvram_state);
266
267   struct vm_device *device = create_device("NVRAM", &dev_ops, nvram_state);
268
269
270   return device;
271 }