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.


nvram updated to provide typical IBM PC data
[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_REG_FLOPPY_TYPE             0x10
40 #define NVRAM_REG_EQUIPMENT_BYTE          0x14
41
42 #define NVRAM_REG_BASE_MEMORY_HIGH        0x16
43 #define NVRAM_REG_BASE_MEMORY_LOW         0x15
44
45 #define NVRAM_REG_EXT_MEMORY_HIGH         0x18
46 #define NVRAM_REG_EXT_MEMORY_LOW          0x17
47
48 #define NVRAM_REG_EXT_MEMORY_2ND_HIGH     0x31
49 #define NVRAM_REG_EXT_MEMORY_2ND_LOW      0x30
50
51 #define NVRAM_REG_BOOTSEQ_OLD             0x2d
52
53 #define NVRAM_REG_AMI_BIG_MEMORY_HIGH     0x35
54 #define NVRAM_REG_AMI_BIG_MEMORY_LOW      0x34
55
56
57 #define NVRAM_REG_CSUM_HIGH               0x2e
58 #define NVRAM_REG_CSUM_LOW                0x2f
59 #define NVRAM_REG_IBM_CENTURY_BYTE        0x32  
60 #define NVRAM_REG_IBM_PS2_CENTURY_BYTE    0x37  
61
62 #define NVRAM_REG_BOOTSEQ_NEW_FIRST       0x3D
63 #define NVRAM_REG_BOOTSEQ_NEW_SECOND      0x38
64
65
66 struct nvram_internal {
67   nvram_state_t dev_state;
68   uchar_t       thereg;
69   uchar_t       mem_state[NVRAM_REG_MAX];
70 };
71
72
73
74 static int set_nvram_defaults(struct vm_device *dev)
75 {
76   struct nvram_internal * nvram_state = (struct nvram_internal*) dev->private_data;
77
78   //
79   // 2 1.44 MB floppy drives
80   //
81   nvram_state->mem_state[NVRAM_REG_FLOPPY_TYPE]= 0x44;
82
83   //
84   // For old boot sequence style, do floppy first
85   //
86   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_OLD]= 0x10;
87
88 #if 0
89   // For new boot sequence style, do floppy, cd, then hd
90   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST]= 0x31;
91   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND]= 0x20;
92 #endif
93
94   // For new boot sequence style, do cd, hd, floppy
95   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_FIRST]= 0x23;
96   nvram_state->mem_state[NVRAM_REG_BOOTSEQ_NEW_SECOND]= 0x10;
97  
98
99   // Set equipment byte to note 2 floppies, vga display, keyboard,math,floppy
100   nvram_state->mem_state[NVRAM_REG_EQUIPMENT_BYTE]= 0x4f;
101
102   // Set conventional memory to 640K
103   nvram_state->mem_state[NVRAM_REG_BASE_MEMORY_HIGH]= 0x02;
104   nvram_state->mem_state[NVRAM_REG_BASE_MEMORY_LOW]= 0x80;
105
106   // Set extended memory to 15 MB
107   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_HIGH]= 0x3C;
108   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_LOW]= 0x00;
109   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_HIGH]= 0x3C;
110   nvram_state->mem_state[NVRAM_REG_EXT_MEMORY_2ND_LOW]= 0x00;
111
112   // Set the extended memory beyond 16 MB to 128-16 MB
113   nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_HIGH]= 0x7;
114   nvram_state->mem_state[NVRAM_REG_AMI_BIG_MEMORY_LOW]= 0x00;
115
116   
117
118   return 0;
119
120 }
121
122
123 int nvram_reset_device(struct vm_device * dev)
124 {
125   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
126   
127   SerialPrint("nvram: reset device\n");
128
129  
130
131   data->dev_state = NVRAM_READY;
132   data->thereg=0;
133
134   
135   return 0;
136
137 }
138
139
140
141
142
143 int nvram_start_device(struct vm_device *dev)
144 {
145   SerialPrint("nvram: start device\n");
146   return 0;
147 }
148
149
150 int nvram_stop_device(struct vm_device *dev)
151 {
152   SerialPrint("nvram: stop device\n");
153   return 0;
154 }
155
156
157
158
159 int nvram_write_reg_port(ushort_t port,
160                         void * src, 
161                         uint_t length,
162                         struct vm_device * dev)
163 {
164   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
165
166   memcpy(&(data->thereg), src, 1);
167
168
169   return 1;
170 }
171
172 int nvram_read_data_port(ushort_t port,
173                        void   * dst, 
174                        uint_t length,
175                        struct vm_device * dev)
176 {
177   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
178
179
180
181   memcpy(dst, &(data->mem_state[data->thereg]), 1);
182
183   SerialPrint("nvram_read_data_port(%x)=%x\n",data->thereg,data->mem_state[data->thereg]);
184
185   return 1;
186 }
187
188 int nvram_write_data_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->mem_state[data->thereg]), src, 1);
196
197   SerialPrint("nvram_write_data_port(%x)=%x\n",data->thereg,data->mem_state[data->thereg]);
198
199   return 1;
200 }
201
202
203
204 int nvram_init_device(struct vm_device * dev) {
205  
206   struct nvram_internal *data = (struct nvram_internal *) dev->private_data;
207
208   SerialPrint("nvram: init_device\n");
209
210   memset(data->mem_state, 0, NVRAM_REG_MAX);
211
212   // Would read state here
213   set_nvram_defaults(dev);
214
215   nvram_reset_device(dev);
216
217   // hook ports
218   dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
219   dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port);
220   
221   return 0;
222 }
223
224 int nvram_deinit_device(struct vm_device *dev)
225 {
226
227
228   dev_unhook_io(dev, NVRAM_REG_PORT);
229   dev_unhook_io(dev, NVRAM_DATA_PORT);
230
231   nvram_reset_device(dev);
232   return 0;
233 }
234
235
236
237
238
239 static struct vm_device_ops dev_ops = { 
240   .init = nvram_init_device, 
241   .deinit = nvram_deinit_device,
242   .reset = nvram_reset_device,
243   .start = nvram_start_device,
244   .stop = nvram_stop_device,
245 };
246
247
248
249
250 struct vm_device *create_nvram() {
251   struct nvram_internal * nvram_state = os_hooks->malloc(sizeof(struct nvram_internal)+1000);
252
253   SerialPrint("internal at %x\n",nvram_state);
254
255   struct vm_device *device = create_device("NVRAM", &dev_ops, nvram_state);
256
257
258   return device;
259 }