Rev 6283 | Rev 6320 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6283 | Rev 6296 | ||
---|---|---|---|
1 | #include |
1 | #include |
2 | 2 | ||
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include "i915_drv.h" |
5 | #include "i915_drv.h" |
6 | 6 | ||
7 | #include |
7 | #include |
8 | #include |
8 | #include |
9 | #include |
9 | #include |
10 | #include |
10 | #include |
11 | 11 | ||
12 | #include "getopt.h" |
12 | #include "getopt.h" |
13 | 13 | ||
14 | #include "bitmap.h" |
14 | #include "bitmap.h" |
15 | #include "i915_kos32.h" |
15 | #include "i915_kos32.h" |
16 | 16 | ||
17 | #define DRV_NAME "i915 v4.4.2-dbg2" |
17 | #define DRV_NAME "i915 v4.4.3" |
18 | 18 | ||
19 | #define I915_DEV_CLOSE 0 |
19 | #define I915_DEV_CLOSE 0 |
20 | #define I915_DEV_INIT 1 |
20 | #define I915_DEV_INIT 1 |
21 | #define I915_DEV_READY 2 |
21 | #define I915_DEV_READY 2 |
22 | 22 | ||
23 | static int my_atoi(char **cmd); |
23 | static int my_atoi(char **cmd); |
24 | static char* parse_mode(char *p, videomode_t *mode); |
24 | static char* parse_mode(char *p, videomode_t *mode); |
25 | void cpu_detect1(); |
25 | void cpu_detect1(); |
26 | int kmap_init(); |
26 | int kmap_init(); |
27 | 27 | ||
28 | unsigned long volatile jiffies; |
28 | unsigned long volatile jiffies; |
29 | int oops_in_progress; |
29 | int oops_in_progress; |
30 | int x86_clflush_size; |
30 | int x86_clflush_size; |
31 | unsigned int tsc_khz; |
31 | unsigned int tsc_khz; |
32 | struct workqueue_struct *system_wq; |
32 | struct workqueue_struct *system_wq; |
33 | int driver_wq_state; |
33 | int driver_wq_state; |
34 | struct drm_device *main_device; |
34 | struct drm_device *main_device; |
35 | struct drm_file *drm_file_handlers[256]; |
35 | struct drm_file *drm_file_handlers[256]; |
36 | videomode_t usermode; |
36 | videomode_t usermode; |
37 | extern int __getopt_initialized; |
37 | extern int __getopt_initialized; |
38 | 38 | ||
39 | void i915_driver_thread() |
39 | void i915_driver_thread() |
40 | { |
40 | { |
41 | struct drm_i915_private *dev_priv = NULL; |
41 | struct drm_i915_private *dev_priv = NULL; |
42 | struct workqueue_struct *cwq = NULL; |
42 | struct workqueue_struct *cwq = NULL; |
43 | static int dpms = 1; |
43 | static int dpms = 1; |
44 | static int dpms_lock = 0; |
44 | static int dpms_lock = 0; |
45 | oskey_t key; |
45 | oskey_t key; |
46 | unsigned long irqflags; |
46 | unsigned long irqflags; |
47 | int tmp; |
47 | int tmp; |
48 | 48 | ||
49 | printf("%s\n",__FUNCTION__); |
49 | printf("%s\n",__FUNCTION__); |
50 | 50 | ||
51 | while(driver_wq_state == I915_DEV_INIT) |
51 | while(driver_wq_state == I915_DEV_INIT) |
52 | { |
52 | { |
53 | jiffies = GetClockNs() / 10000000; |
53 | jiffies = GetClockNs() / 10000000; |
54 | delay(1); |
54 | delay(1); |
55 | }; |
55 | }; |
56 | 56 | ||
57 | if( driver_wq_state == I915_DEV_CLOSE) |
57 | if( driver_wq_state == I915_DEV_CLOSE) |
58 | { |
58 | { |
59 | asm volatile ("int $0x40"::"a"(-1)); |
59 | asm volatile ("int $0x40"::"a"(-1)); |
60 | }; |
60 | }; |
61 | 61 | ||
62 | dev_priv = main_device->dev_private; |
62 | dev_priv = main_device->dev_private; |
63 | cwq = dev_priv->wq; |
- | |
64 | 63 | ||
65 | asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(1),"c"(1)); |
64 | asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(1),"c"(1)); |
66 | asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(4),"c"(0x46),"d"(0x330)); |
65 | asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(4),"c"(0x46),"d"(0x330)); |
67 | asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(4),"c"(0xC6),"d"(0x330)); |
66 | asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(4),"c"(0xC6),"d"(0x330)); |
68 | 67 | ||
69 | while(driver_wq_state != I915_DEV_CLOSE) |
68 | while(driver_wq_state != I915_DEV_CLOSE) |
70 | { |
69 | { |
71 | jiffies = GetClockNs() / 10000000; |
70 | jiffies = GetClockNs() / 10000000; |
72 | 71 | ||
73 | key = get_key(); |
72 | key = get_key(); |
74 | 73 | ||
75 | if( (key.val != 1) && (key.state == 0x02)) |
74 | if( (key.val != 1) && (key.state == 0x02)) |
76 | { |
75 | { |
77 | if(key.code == 0x46 && dpms_lock == 0) |
76 | if(key.code == 0x46 && dpms_lock == 0) |
78 | { |
77 | { |
79 | dpms_lock = 1; |
78 | dpms_lock = 1; |
80 | if(dpms == 1) |
79 | if(dpms == 1) |
81 | { |
80 | { |
82 | i915_dpms(main_device, DRM_MODE_DPMS_OFF); |
81 | i915_dpms(main_device, DRM_MODE_DPMS_OFF); |
83 | printf("dpms off\n"); |
82 | printf("dpms off\n"); |
84 | } |
83 | } |
85 | else |
84 | else |
86 | { |
85 | { |
87 | i915_dpms(main_device, DRM_MODE_DPMS_ON); |
86 | i915_dpms(main_device, DRM_MODE_DPMS_ON); |
88 | printf("dpms on\n"); |
87 | printf("dpms on\n"); |
89 | }; |
88 | }; |
90 | dpms ^= 1; |
89 | dpms ^= 1; |
91 | } |
90 | } |
92 | else if(key.code == 0xC6) |
91 | else if(key.code == 0xC6) |
93 | dpms_lock = 0; |
92 | dpms_lock = 0; |
94 | }; |
93 | }; |
- | 94 | cwq = dev_priv->wq; |
|
95 | 95 | ||
96 | spin_lock_irqsave(&cwq->lock, irqflags); |
- | |
97 | 96 | spin_lock_irqsave(&cwq->lock, irqflags); |
|
98 | while (!list_empty(&cwq->worklist)) |
97 | while (!list_empty(&cwq->worklist)) |
99 | { |
98 | { |
100 | struct work_struct *work = list_entry(cwq->worklist.next, |
99 | struct work_struct *work = list_entry(cwq->worklist.next, |
101 | struct work_struct, entry); |
100 | struct work_struct, entry); |
102 | work_func_t f = work->func; |
101 | work_func_t f = work->func; |
103 | list_del_init(cwq->worklist.next); |
102 | list_del_init(cwq->worklist.next); |
104 | 103 | ||
105 | spin_unlock_irqrestore(&cwq->lock, irqflags); |
104 | spin_unlock_irqrestore(&cwq->lock, irqflags); |
106 | f(work); |
105 | f(work); |
107 | spin_lock_irqsave(&cwq->lock, irqflags); |
106 | spin_lock_irqsave(&cwq->lock, irqflags); |
108 | } |
107 | } |
- | 108 | spin_unlock_irqrestore(&cwq->lock, irqflags); |
|
- | 109 | ||
- | 110 | cwq = dev_priv->hotplug.dp_wq; |
|
- | 111 | ||
- | 112 | spin_lock_irqsave(&cwq->lock, irqflags); |
|
- | 113 | while (!list_empty(&cwq->worklist)) |
|
- | 114 | { |
|
- | 115 | struct work_struct *work = list_entry(cwq->worklist.next, |
|
- | 116 | struct work_struct, entry); |
|
- | 117 | work_func_t f = work->func; |
|
- | 118 | list_del_init(cwq->worklist.next); |
|
- | 119 | ||
- | 120 | spin_unlock_irqrestore(&cwq->lock, irqflags); |
|
- | 121 | f(work); |
|
- | 122 | spin_lock_irqsave(&cwq->lock, irqflags); |
|
109 | 123 | } |
|
110 | spin_unlock_irqrestore(&cwq->lock, irqflags); |
124 | spin_unlock_irqrestore(&cwq->lock, irqflags); |
111 | 125 | ||
112 | delay(1); |
126 | delay(1); |
113 | }; |
127 | }; |
114 | 128 | ||
115 | asm volatile ("int $0x40"::"a"(-1)); |
129 | asm volatile ("int $0x40"::"a"(-1)); |
116 | } |
130 | } |
117 | 131 | ||
118 | u32 __attribute__((externally_visible)) drvEntry(int action, char *cmdline) |
132 | u32 __attribute__((externally_visible)) drvEntry(int action, char *cmdline) |
119 | { |
133 | { |
120 | static pci_dev_t device; |
134 | static pci_dev_t device; |
121 | const struct pci_device_id *ent; |
135 | const struct pci_device_id *ent; |
122 | char *safecmdline; |
136 | char *safecmdline; |
123 | int err = 0; |
137 | int err = 0; |
124 | 138 | ||
125 | if(action != 1) |
139 | if(action != 1) |
126 | { |
140 | { |
127 | driver_wq_state = I915_DEV_CLOSE; |
141 | driver_wq_state = I915_DEV_CLOSE; |
128 | return 0; |
142 | return 0; |
129 | }; |
143 | }; |
130 | 144 | ||
131 | if( GetService("DISPLAY") != 0 ) |
145 | if( GetService("DISPLAY") != 0 ) |
132 | return 0; |
146 | return 0; |
133 | 147 | ||
134 | printf("\n%s build %s %s\nusage: i915 [options]\n", |
148 | printf("\n%s build %s %s\nusage: i915 [options]\n", |
135 | DRV_NAME, __DATE__, __TIME__); |
149 | DRV_NAME, __DATE__, __TIME__); |
136 | 150 | ||
137 | printf("--rc6 <-1,0-7> Enable power-saving render C-state 6.\n" |
151 | printf("--rc6 <-1,0-7> Enable power-saving render C-state 6.\n" |
138 | " Different stages can be selected via bitmask values\n" |
152 | " Different stages can be selected via bitmask values\n" |
139 | " (0 = disable; 1 = enable rc6; 2 = enable deep rc6;\n" |
153 | " (0 = disable; 1 = enable rc6; 2 = enable deep rc6;\n" |
140 | " 4 = enable deepest rc6).\n" |
154 | " 4 = enable deepest rc6).\n" |
141 | " For example, 3 would enable rc6 and deep rc6,\n" |
155 | " For example, 3 would enable rc6 and deep rc6,\n" |
142 | " and 7 would enable everything.\n" |
156 | " and 7 would enable everything.\n" |
143 | " default: -1 (use per-chip default)\n"); |
157 | " default: -1 (use per-chip default)\n"); |
144 | printf("--fbc <-1,0,1> Enable frame buffer compression for power savings\n" |
158 | printf("--fbc <-1,0,1> Enable frame buffer compression for power savings\n" |
145 | " (default: -1 (use per-chip default))\n"); |
159 | " (default: -1 (use per-chip default))\n"); |
146 | printf("-l\n" |
160 | printf("-l\n" |
147 | "--log |
161 | "--log |
148 | printf("-m\n" |
162 | printf("-m\n" |
149 | "--mode |
163 | "--mode |
150 | printf("-v\n" |
164 | printf("-v\n" |
151 | "--video |
165 | "--video |
152 | " set videomode for CONNECTOR\n"); |
166 | " set videomode for CONNECTOR\n"); |
153 | 167 | ||
154 | if( cmdline && *cmdline ) |
168 | if( cmdline && *cmdline ) |
155 | { |
169 | { |
156 | int argc, i, c; |
170 | int argc, i, c; |
157 | char **argv; |
171 | char **argv; |
158 | 172 | ||
159 | safecmdline = __builtin_strdup(cmdline); |
173 | safecmdline = __builtin_strdup(cmdline); |
160 | printf("cmdline %s\n", safecmdline); |
174 | printf("cmdline %s\n", safecmdline); |
161 | 175 | ||
162 | argc = split_cmdline(safecmdline, NULL); |
176 | argc = split_cmdline(safecmdline, NULL); |
163 | argv = __builtin_malloc((argc+1)*sizeof(char*)); |
177 | argv = __builtin_malloc((argc+1)*sizeof(char*)); |
164 | split_cmdline(safecmdline, argv); |
178 | split_cmdline(safecmdline, argv); |
165 | argv[argc] = NULL; |
179 | argv[argc] = NULL; |
166 | 180 | ||
167 | while(1) |
181 | while(1) |
168 | { |
182 | { |
169 | static struct option long_options[] = |
183 | static struct option long_options[] = |
170 | { |
184 | { |
171 | {"log", required_argument, 0, 'l'}, |
185 | {"log", required_argument, 0, 'l'}, |
172 | {"mode", required_argument, 0, 'm'}, |
186 | {"mode", required_argument, 0, 'm'}, |
173 | {"video", required_argument, 0, 'v'}, |
187 | {"video", required_argument, 0, 'v'}, |
174 | {"rc6", required_argument, 0, OPTION_RC6}, |
188 | {"rc6", required_argument, 0, OPTION_RC6}, |
175 | {"fbc", required_argument, 0, OPTION_FBC}, |
189 | {"fbc", required_argument, 0, OPTION_FBC}, |
176 | {0, 0, 0, 0} |
190 | {0, 0, 0, 0} |
177 | }; |
191 | }; |
178 | 192 | ||
179 | int option_index = 0; |
193 | int option_index = 0; |
180 | 194 | ||
181 | c = getopt_long (argc, argv, "l:m:v:", |
195 | c = getopt_long (argc, argv, "l:m:v:", |
182 | long_options, &option_index); |
196 | long_options, &option_index); |
183 | 197 | ||
184 | if (c == -1) |
198 | if (c == -1) |
185 | break; |
199 | break; |
186 | 200 | ||
187 | switch(c) |
201 | switch(c) |
188 | { |
202 | { |
189 | case OPTION_RC6: |
203 | case OPTION_RC6: |
190 | i915.enable_rc6 = my_atoi(&optarg); |
204 | i915.enable_rc6 = my_atoi(&optarg); |
191 | printf("i915.rc6 = %d\n",i915.enable_rc6); |
205 | printf("i915.rc6 = %d\n",i915.enable_rc6); |
192 | break; |
206 | break; |
193 | 207 | ||
194 | case OPTION_FBC: |
208 | case OPTION_FBC: |
195 | i915.enable_fbc = my_atoi(&optarg); |
209 | i915.enable_fbc = my_atoi(&optarg); |
196 | printf("i915.fbc = %d\n",i915.enable_fbc); |
210 | printf("i915.fbc = %d\n",i915.enable_fbc); |
197 | break; |
211 | break; |
198 | 212 | ||
199 | case 'l': |
213 | case 'l': |
200 | i915.log_file = optarg; |
214 | i915.log_file = optarg; |
201 | break; |
215 | break; |
202 | 216 | ||
203 | case 'm': |
217 | case 'm': |
204 | parse_mode(optarg, &usermode); |
218 | parse_mode(optarg, &usermode); |
205 | break; |
219 | break; |
206 | 220 | ||
207 | case 'v': |
221 | case 'v': |
208 | i915.cmdline_mode = optarg; |
222 | i915.cmdline_mode = optarg; |
209 | printf("i915.cmdline_mode =%s\n",i915.cmdline_mode); |
223 | printf("i915.cmdline_mode =%s\n",i915.cmdline_mode); |
210 | break; |
224 | break; |
211 | } |
225 | } |
212 | } |
226 | } |
213 | }; |
227 | }; |
214 | 228 | ||
215 | if( i915.log_file && !dbg_open(i915.log_file)) |
229 | if( i915.log_file && !dbg_open(i915.log_file)) |
216 | { |
230 | { |
217 | printf("Can't open %s\nExit\n", i915.log_file); |
231 | printf("Can't open %s\nExit\n", i915.log_file); |
218 | return 0; |
232 | return 0; |
219 | } |
233 | } |
220 | else |
234 | else |
221 | { |
235 | { |
222 | dbgprintf("\nLOG: %s build %s %s\n",DRV_NAME,__DATE__, __TIME__); |
236 | dbgprintf("\nLOG: %s build %s %s\n",DRV_NAME,__DATE__, __TIME__); |
223 | } |
237 | } |
224 | 238 | ||
225 | cpu_detect1(); |
239 | cpu_detect1(); |
226 | 240 | ||
227 | err = enum_pci_devices(); |
241 | err = enum_pci_devices(); |
228 | if( unlikely(err != 0) ) |
242 | if( unlikely(err != 0) ) |
229 | { |
243 | { |
230 | dbgprintf("Device enumeration failed\n"); |
244 | dbgprintf("Device enumeration failed\n"); |
231 | return 0; |
245 | return 0; |
232 | } |
246 | } |
233 | 247 | ||
234 | err = kmap_init(); |
248 | err = kmap_init(); |
235 | if( unlikely(err != 0) ) |
249 | if( unlikely(err != 0) ) |
236 | { |
250 | { |
237 | dbgprintf("kmap initialization failed\n"); |
251 | dbgprintf("kmap initialization failed\n"); |
238 | return 0; |
252 | return 0; |
239 | } |
253 | } |
240 | 254 | ||
241 | dmi_scan_machine(); |
255 | dmi_scan_machine(); |
242 | 256 | ||
243 | driver_wq_state = I915_DEV_INIT; |
257 | driver_wq_state = I915_DEV_INIT; |
244 | CreateKernelThread(i915_driver_thread); |
258 | CreateKernelThread(i915_driver_thread); |
245 | 259 | ||
246 | err = i915_init(); |
260 | err = i915_init(); |
247 | if(unlikely(err!= 0)) |
261 | if(unlikely(err!= 0)) |
248 | { |
262 | { |
249 | driver_wq_state = I915_DEV_CLOSE; |
263 | driver_wq_state = I915_DEV_CLOSE; |
250 | dbgprintf("Epic Fail :(\n"); |
264 | dbgprintf("Epic Fail :(\n"); |
251 | delay(100); |
265 | delay(100); |
252 | return 0; |
266 | return 0; |
253 | }; |
267 | }; |
254 | 268 | ||
255 | driver_wq_state = I915_DEV_READY; |
269 | driver_wq_state = I915_DEV_READY; |
256 | 270 | ||
257 | init_display_kms(main_device, &usermode); |
271 | init_display_kms(main_device, &usermode); |
258 | 272 | ||
259 | err = RegService("DISPLAY", display_handler); |
273 | err = RegService("DISPLAY", display_handler); |
260 | 274 | ||
261 | if( err != 0) |
275 | if( err != 0) |
262 | dbgprintf("Set DISPLAY handler\n"); |
276 | dbgprintf("Set DISPLAY handler\n"); |
263 | 277 | ||
264 | return err; |
278 | return err; |
265 | }; |
279 | }; |
266 | 280 | ||
267 | int do_command_line(const char* usercmd) |
281 | int do_command_line(const char* usercmd) |
268 | { |
282 | { |
269 | char *cmdline; |
283 | char *cmdline; |
270 | int argc, i, c; |
284 | int argc, i, c; |
271 | char **argv; |
285 | char **argv; |
272 | int retval = 0; |
286 | int retval = 0; |
273 | 287 | ||
274 | if( (usercmd == NULL) || (*usercmd == 0) ) |
288 | if( (usercmd == NULL) || (*usercmd == 0) ) |
275 | return 1; |
289 | return 1; |
276 | 290 | ||
277 | cmdline = __builtin_strdup(usercmd); |
291 | cmdline = __builtin_strdup(usercmd); |
278 | printf("cmdline %s\n", cmdline); |
292 | printf("cmdline %s\n", cmdline); |
279 | 293 | ||
280 | argc = split_cmdline(cmdline, NULL); |
294 | argc = split_cmdline(cmdline, NULL); |
281 | argv = __builtin_malloc((argc+1)*sizeof(char*)); |
295 | argv = __builtin_malloc((argc+1)*sizeof(char*)); |
282 | split_cmdline(cmdline, argv); |
296 | split_cmdline(cmdline, argv); |
283 | argv[argc] = NULL; |
297 | argv[argc] = NULL; |
284 | 298 | ||
285 | __getopt_initialized = 0; |
299 | __getopt_initialized = 0; |
286 | 300 | ||
287 | while(1) |
301 | while(1) |
288 | { |
302 | { |
289 | static struct option long_options[] = |
303 | static struct option long_options[] = |
290 | { |
304 | { |
291 | {"list-connectors", no_argument, 0, OPTION_CONNECTORS}, |
305 | {"list-connectors", no_argument, 0, OPTION_CONNECTORS}, |
292 | {"list-connector-modes", required_argument, 0, OPTION_CONN_MODES}, |
306 | {"list-connector-modes", required_argument, 0, OPTION_CONN_MODES}, |
293 | {"video", required_argument, 0, 'v'}, |
307 | {"video", required_argument, 0, 'v'}, |
294 | {0, 0, 0, 0} |
308 | {0, 0, 0, 0} |
295 | }; |
309 | }; |
296 | 310 | ||
297 | int option_index = 0; |
311 | int option_index = 0; |
298 | 312 | ||
299 | c = getopt_long (argc, argv, "v:", |
313 | c = getopt_long (argc, argv, "v:", |
300 | long_options, &option_index); |
314 | long_options, &option_index); |
301 | 315 | ||
302 | if (c == -1) |
316 | if (c == -1) |
303 | break; |
317 | break; |
304 | 318 | ||
305 | switch(c) |
319 | switch(c) |
306 | { |
320 | { |
307 | case 'v': |
321 | case 'v': |
308 | printf("cmdline_mode %s\n",optarg); |
322 | printf("cmdline_mode %s\n",optarg); |
309 | retval = set_cmdline_mode_ext(main_device, optarg); |
323 | retval = set_cmdline_mode_ext(main_device, optarg); |
310 | break; |
324 | break; |
311 | 325 | ||
312 | case OPTION_CONNECTORS: |
326 | case OPTION_CONNECTORS: |
313 | list_connectors(main_device); |
327 | list_connectors(main_device); |
314 | break; |
328 | break; |
315 | 329 | ||
316 | case OPTION_CONN_MODES: |
330 | case OPTION_CONN_MODES: |
317 | retval = list_connector_modes(main_device, optarg); |
331 | retval = list_connector_modes(main_device, optarg); |
318 | break; |
332 | break; |
319 | } |
333 | } |
320 | } |
334 | } |
321 | __builtin_free(argv); |
335 | __builtin_free(argv); |
322 | __builtin_free(cmdline); |
336 | __builtin_free(cmdline); |
323 | 337 | ||
324 | return retval; |
338 | return retval; |
325 | }; |
339 | }; |
326 | 340 | ||
327 | #define CURRENT_API 0x0200 /* 2.00 */ |
341 | #define CURRENT_API 0x0200 /* 2.00 */ |
328 | #define COMPATIBLE_API 0x0100 /* 1.00 */ |
342 | #define COMPATIBLE_API 0x0100 /* 1.00 */ |
329 | 343 | ||
330 | #define API_VERSION (COMPATIBLE_API << 16) | CURRENT_API |
344 | #define API_VERSION (COMPATIBLE_API << 16) | CURRENT_API |
331 | #define DISPLAY_VERSION API_VERSION |
345 | #define DISPLAY_VERSION API_VERSION |
332 | 346 | ||
333 | 347 | ||
334 | #define SRV_GETVERSION 0 |
348 | #define SRV_GETVERSION 0 |
335 | #define SRV_ENUM_MODES 1 |
349 | #define SRV_ENUM_MODES 1 |
336 | #define SRV_SET_MODE 2 |
350 | #define SRV_SET_MODE 2 |
337 | #define SRV_GET_CAPS 3 |
351 | #define SRV_GET_CAPS 3 |
338 | #define SRV_CMDLINE 4 |
352 | #define SRV_CMDLINE 4 |
339 | 353 | ||
340 | #define SRV_GET_PCI_INFO 20 |
354 | #define SRV_GET_PCI_INFO 20 |
341 | #define SRV_I915_GET_PARAM 21 |
355 | #define SRV_I915_GET_PARAM 21 |
342 | #define SRV_I915_GEM_CREATE 22 |
356 | #define SRV_I915_GEM_CREATE 22 |
343 | #define SRV_DRM_GEM_CLOSE 23 |
357 | #define SRV_DRM_GEM_CLOSE 23 |
344 | #define SRV_DRM_GEM_FLINK 24 |
358 | #define SRV_DRM_GEM_FLINK 24 |
345 | #define SRV_DRM_GEM_OPEN 25 |
359 | #define SRV_DRM_GEM_OPEN 25 |
346 | #define SRV_I915_GEM_PIN 26 |
360 | #define SRV_I915_GEM_PIN 26 |
347 | #define SRV_I915_GEM_UNPIN 27 |
361 | #define SRV_I915_GEM_UNPIN 27 |
348 | #define SRV_I915_GEM_GET_CACHING 28 |
362 | #define SRV_I915_GEM_GET_CACHING 28 |
349 | #define SRV_I915_GEM_SET_CACHING 29 |
363 | #define SRV_I915_GEM_SET_CACHING 29 |
350 | #define SRV_I915_GEM_PWRITE 30 |
364 | #define SRV_I915_GEM_PWRITE 30 |
351 | #define SRV_I915_GEM_BUSY 31 |
365 | #define SRV_I915_GEM_BUSY 31 |
352 | #define SRV_I915_GEM_SET_DOMAIN 32 |
366 | #define SRV_I915_GEM_SET_DOMAIN 32 |
353 | #define SRV_I915_GEM_MMAP 33 |
367 | #define SRV_I915_GEM_MMAP 33 |
354 | #define SRV_I915_GEM_SET_TILING 34 |
368 | #define SRV_I915_GEM_SET_TILING 34 |
355 | #define SRV_I915_GEM_GET_TILING 35 |
369 | #define SRV_I915_GEM_GET_TILING 35 |
356 | #define SRV_I915_GEM_GET_APERTURE 36 |
370 | #define SRV_I915_GEM_GET_APERTURE 36 |
357 | #define SRV_I915_GEM_MMAP_GTT 37 |
371 | #define SRV_I915_GEM_MMAP_GTT 37 |
358 | #define SRV_I915_GEM_THROTTLE 38 |
372 | #define SRV_I915_GEM_THROTTLE 38 |
359 | #define SRV_I915_GEM_EXECBUFFER2 39 |
373 | #define SRV_I915_GEM_EXECBUFFER2 39 |
360 | #define SRV_I915_GEM_WAIT 40 |
374 | #define SRV_I915_GEM_WAIT 40 |
361 | #define SRV_I915_GEM_CONTEXT_CREATE 41 |
375 | #define SRV_I915_GEM_CONTEXT_CREATE 41 |
362 | #define SRV_I915_GEM_CONTEXT_DESTROY 42 |
376 | #define SRV_I915_GEM_CONTEXT_DESTROY 42 |
363 | #define SRV_I915_REG_READ 43 |
377 | #define SRV_I915_REG_READ 43 |
364 | 378 | ||
365 | #define SRV_FBINFO 44 |
379 | #define SRV_FBINFO 44 |
366 | #define SRV_MASK_UPDATE 45 |
380 | #define SRV_MASK_UPDATE 45 |
367 | #define SRV_MASK_UPDATE_EX 46 |
381 | #define SRV_MASK_UPDATE_EX 46 |
368 | 382 | ||
369 | #define SRV_I915_GEM_PREAD 47 |
383 | #define SRV_I915_GEM_PREAD 47 |
370 | 384 | ||
371 | #define check_input(size) \ |
385 | #define check_input(size) \ |
372 | if( unlikely((inp==NULL)||(io->inp_size != (size))) ) \ |
386 | if( unlikely((inp==NULL)||(io->inp_size != (size))) ) \ |
373 | break; |
387 | break; |
374 | 388 | ||
375 | #define check_output(size) \ |
389 | #define check_output(size) \ |
376 | if( unlikely((outp==NULL)||(io->out_size != (size))) ) \ |
390 | if( unlikely((outp==NULL)||(io->out_size != (size))) ) \ |
377 | break; |
391 | break; |
378 | 392 | ||
379 | int _stdcall display_handler(ioctl_t *io) |
393 | int _stdcall display_handler(ioctl_t *io) |
380 | { |
394 | { |
381 | struct drm_file *file; |
395 | struct drm_file *file; |
382 | 396 | ||
383 | int retval = -1; |
397 | int retval = -1; |
384 | u32 *inp; |
398 | u32 *inp; |
385 | u32 *outp; |
399 | u32 *outp; |
386 | 400 | ||
387 | inp = io->input; |
401 | inp = io->input; |
388 | outp = io->output; |
402 | outp = io->output; |
389 | 403 | ||
390 | file = drm_file_handlers[0]; |
404 | file = drm_file_handlers[0]; |
391 | 405 | ||
392 | switch(io->io_code) |
406 | switch(io->io_code) |
393 | { |
407 | { |
394 | case SRV_GETVERSION: |
408 | case SRV_GETVERSION: |
395 | check_output(4); |
409 | check_output(4); |
396 | *outp = DISPLAY_VERSION; |
410 | *outp = DISPLAY_VERSION; |
397 | retval = 0; |
411 | retval = 0; |
398 | break; |
412 | break; |
399 | 413 | ||
400 | case SRV_ENUM_MODES: |
414 | case SRV_ENUM_MODES: |
401 | // dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n", |
415 | // dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n", |
402 | // inp, io->inp_size, io->out_size ); |
416 | // inp, io->inp_size, io->out_size ); |
403 | check_output(4); |
417 | check_output(4); |
404 | // check_input(*outp * sizeof(videomode_t)); |
418 | // check_input(*outp * sizeof(videomode_t)); |
405 | retval = get_videomodes((videomode_t*)inp, outp); |
419 | retval = get_videomodes((videomode_t*)inp, outp); |
406 | break; |
420 | break; |
407 | 421 | ||
408 | case SRV_SET_MODE: |
422 | case SRV_SET_MODE: |
409 | // dbgprintf("SRV_SET_MODE inp %x inp_size %x\n", |
423 | // dbgprintf("SRV_SET_MODE inp %x inp_size %x\n", |
410 | // inp, io->inp_size); |
424 | // inp, io->inp_size); |
411 | check_input(sizeof(videomode_t)); |
425 | check_input(sizeof(videomode_t)); |
412 | retval = set_user_mode((videomode_t*)inp); |
426 | retval = set_user_mode((videomode_t*)inp); |
413 | break; |
427 | break; |
414 | 428 | ||
415 | case SRV_GET_CAPS: |
429 | case SRV_GET_CAPS: |
416 | retval = get_driver_caps((hwcaps_t*)inp); |
430 | retval = get_driver_caps((hwcaps_t*)inp); |
417 | break; |
431 | break; |
418 | 432 | ||
419 | case SRV_CMDLINE: |
433 | case SRV_CMDLINE: |
420 | retval = do_command_line((char*)inp); |
434 | retval = do_command_line((char*)inp); |
421 | break; |
435 | break; |
422 | 436 | ||
423 | case SRV_GET_PCI_INFO: |
437 | case SRV_GET_PCI_INFO: |
424 | get_pci_info((struct pci_device *)inp); |
438 | get_pci_info((struct pci_device *)inp); |
425 | retval = 0; |
439 | retval = 0; |
426 | break; |
440 | break; |
427 | 441 | ||
428 | case SRV_I915_GET_PARAM: |
442 | case SRV_I915_GET_PARAM: |
429 | retval = i915_getparam(main_device, inp, file); |
443 | retval = i915_getparam(main_device, inp, file); |
430 | break; |
444 | break; |
431 | 445 | ||
432 | case SRV_I915_GEM_CREATE: |
446 | case SRV_I915_GEM_CREATE: |
433 | retval = i915_gem_create_ioctl(main_device, inp, file); |
447 | retval = i915_gem_create_ioctl(main_device, inp, file); |
434 | break; |
448 | break; |
435 | 449 | ||
436 | case SRV_DRM_GEM_CLOSE: |
450 | case SRV_DRM_GEM_CLOSE: |
437 | retval = drm_gem_close_ioctl(main_device, inp, file); |
451 | retval = drm_gem_close_ioctl(main_device, inp, file); |
438 | break; |
452 | break; |
439 | 453 | ||
440 | case SRV_DRM_GEM_FLINK: |
454 | case SRV_DRM_GEM_FLINK: |
441 | retval = drm_gem_flink_ioctl(main_device, inp, file); |
455 | retval = drm_gem_flink_ioctl(main_device, inp, file); |
442 | break; |
456 | break; |
443 | 457 | ||
444 | case SRV_DRM_GEM_OPEN: |
458 | case SRV_DRM_GEM_OPEN: |
445 | retval = drm_gem_open_ioctl(main_device, inp, file); |
459 | retval = drm_gem_open_ioctl(main_device, inp, file); |
446 | break; |
460 | break; |
447 | 461 | ||
448 | case SRV_I915_GEM_GET_CACHING: |
462 | case SRV_I915_GEM_GET_CACHING: |
449 | retval = i915_gem_get_caching_ioctl(main_device, inp, file); |
463 | retval = i915_gem_get_caching_ioctl(main_device, inp, file); |
450 | break; |
464 | break; |
451 | 465 | ||
452 | case SRV_I915_GEM_SET_CACHING: |
466 | case SRV_I915_GEM_SET_CACHING: |
453 | retval = i915_gem_set_caching_ioctl(main_device, inp, file); |
467 | retval = i915_gem_set_caching_ioctl(main_device, inp, file); |
454 | break; |
468 | break; |
455 | 469 | ||
456 | case SRV_I915_GEM_PREAD: |
470 | case SRV_I915_GEM_PREAD: |
457 | retval = i915_gem_pread_ioctl(main_device, inp, file); |
471 | retval = i915_gem_pread_ioctl(main_device, inp, file); |
458 | break; |
472 | break; |
459 | 473 | ||
460 | case SRV_I915_GEM_PWRITE: |
474 | case SRV_I915_GEM_PWRITE: |
461 | retval = i915_gem_pwrite_ioctl(main_device, inp, file); |
475 | retval = i915_gem_pwrite_ioctl(main_device, inp, file); |
462 | break; |
476 | break; |
463 | 477 | ||
464 | case SRV_I915_GEM_BUSY: |
478 | case SRV_I915_GEM_BUSY: |
465 | retval = i915_gem_busy_ioctl(main_device, inp, file); |
479 | retval = i915_gem_busy_ioctl(main_device, inp, file); |
466 | break; |
480 | break; |
467 | 481 | ||
468 | case SRV_I915_GEM_SET_DOMAIN: |
482 | case SRV_I915_GEM_SET_DOMAIN: |
469 | retval = i915_gem_set_domain_ioctl(main_device, inp, file); |
483 | retval = i915_gem_set_domain_ioctl(main_device, inp, file); |
470 | break; |
484 | break; |
471 | 485 | ||
472 | case SRV_I915_GEM_MMAP: |
486 | case SRV_I915_GEM_MMAP: |
473 | retval = i915_gem_mmap_ioctl(main_device, inp, file); |
487 | retval = i915_gem_mmap_ioctl(main_device, inp, file); |
474 | break; |
488 | break; |
475 | 489 | ||
476 | case SRV_I915_GEM_SET_TILING: |
490 | case SRV_I915_GEM_SET_TILING: |
477 | retval = i915_gem_set_tiling(main_device, inp, file); |
491 | retval = i915_gem_set_tiling(main_device, inp, file); |
478 | break; |
492 | break; |
479 | 493 | ||
480 | case SRV_I915_GEM_GET_TILING: |
494 | case SRV_I915_GEM_GET_TILING: |
481 | retval = i915_gem_get_tiling(main_device, inp, file); |
495 | retval = i915_gem_get_tiling(main_device, inp, file); |
482 | break; |
496 | break; |
483 | 497 | ||
484 | case SRV_I915_GEM_GET_APERTURE: |
498 | case SRV_I915_GEM_GET_APERTURE: |
485 | // printf("SRV_I915_GEM_GET_APERTURE "); |
499 | // printf("SRV_I915_GEM_GET_APERTURE "); |
486 | retval = i915_gem_get_aperture_ioctl(main_device, inp, file); |
500 | retval = i915_gem_get_aperture_ioctl(main_device, inp, file); |
487 | // printf(" retval=%d\n", retval); |
501 | // printf(" retval=%d\n", retval); |
488 | break; |
502 | break; |
489 | 503 | ||
490 | case SRV_I915_GEM_MMAP_GTT: |
504 | case SRV_I915_GEM_MMAP_GTT: |
491 | retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file); |
505 | retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file); |
492 | break; |
506 | break; |
493 | 507 | ||
494 | case SRV_I915_GEM_THROTTLE: |
508 | case SRV_I915_GEM_THROTTLE: |
495 | retval = i915_gem_throttle_ioctl(main_device, inp, file); |
509 | retval = i915_gem_throttle_ioctl(main_device, inp, file); |
496 | break; |
510 | break; |
497 | 511 | ||
498 | case SRV_I915_GEM_EXECBUFFER2: |
512 | case SRV_I915_GEM_EXECBUFFER2: |
499 | retval = i915_gem_execbuffer2(main_device, inp, file); |
513 | retval = i915_gem_execbuffer2(main_device, inp, file); |
500 | break; |
514 | break; |
501 | 515 | ||
502 | case SRV_I915_GEM_WAIT: |
516 | case SRV_I915_GEM_WAIT: |
503 | retval = i915_gem_wait_ioctl(main_device, inp, file); |
517 | retval = i915_gem_wait_ioctl(main_device, inp, file); |
504 | break; |
518 | break; |
505 | 519 | ||
506 | case SRV_I915_GEM_CONTEXT_CREATE: |
520 | case SRV_I915_GEM_CONTEXT_CREATE: |
507 | retval = i915_gem_context_create_ioctl(main_device, inp, file); |
521 | retval = i915_gem_context_create_ioctl(main_device, inp, file); |
508 | break; |
522 | break; |
509 | 523 | ||
510 | case SRV_I915_GEM_CONTEXT_DESTROY: |
524 | case SRV_I915_GEM_CONTEXT_DESTROY: |
511 | retval = i915_gem_context_destroy_ioctl(main_device, inp, file); |
525 | retval = i915_gem_context_destroy_ioctl(main_device, inp, file); |
512 | break; |
526 | break; |
513 | 527 | ||
514 | case SRV_I915_REG_READ: |
528 | case SRV_I915_REG_READ: |
515 | retval = i915_reg_read_ioctl(main_device, inp, file); |
529 | retval = i915_reg_read_ioctl(main_device, inp, file); |
516 | break; |
530 | break; |
517 | 531 | ||
518 | case SRV_FBINFO: |
532 | case SRV_FBINFO: |
519 | retval = i915_fbinfo(inp); |
533 | retval = i915_fbinfo(inp); |
520 | break; |
534 | break; |
521 | 535 | ||
522 | case SRV_MASK_UPDATE: |
536 | case SRV_MASK_UPDATE: |
523 | retval = i915_mask_update(main_device, inp, file); |
537 | retval = i915_mask_update(main_device, inp, file); |
524 | break; |
538 | break; |
525 | 539 | ||
526 | case SRV_MASK_UPDATE_EX: |
540 | case SRV_MASK_UPDATE_EX: |
527 | retval = i915_mask_update_ex(main_device, inp, file); |
541 | retval = i915_mask_update_ex(main_device, inp, file); |
528 | break; |
542 | break; |
529 | }; |
543 | }; |
530 | 544 | ||
531 | return retval; |
545 | return retval; |
532 | } |
546 | } |
533 | 547 | ||
534 | 548 | ||
535 | #define PCI_CLASS_REVISION 0x08 |
549 | #define PCI_CLASS_REVISION 0x08 |
536 | #define PCI_CLASS_DISPLAY_VGA 0x0300 |
550 | #define PCI_CLASS_DISPLAY_VGA 0x0300 |
537 | #define PCI_CLASS_BRIDGE_HOST 0x0600 |
551 | #define PCI_CLASS_BRIDGE_HOST 0x0600 |
538 | #define PCI_CLASS_BRIDGE_ISA 0x0601 |
552 | #define PCI_CLASS_BRIDGE_ISA 0x0601 |
539 | 553 | ||
540 | int pci_scan_filter(u32 id, u32 busnr, u32 devfn) |
554 | int pci_scan_filter(u32 id, u32 busnr, u32 devfn) |
541 | { |
555 | { |
542 | u16 vendor, device; |
556 | u16 vendor, device; |
543 | u32 class; |
557 | u32 class; |
544 | int ret = 0; |
558 | int ret = 0; |
545 | 559 | ||
546 | vendor = id & 0xffff; |
560 | vendor = id & 0xffff; |
547 | device = (id >> 16) & 0xffff; |
561 | device = (id >> 16) & 0xffff; |
548 | 562 | ||
549 | if(vendor == 0x8086) |
563 | if(vendor == 0x8086) |
550 | { |
564 | { |
551 | class = PciRead32(busnr, devfn, PCI_CLASS_REVISION); |
565 | class = PciRead32(busnr, devfn, PCI_CLASS_REVISION); |
552 | class >>= 16; |
566 | class >>= 16; |
553 | 567 | ||
554 | if( (class == PCI_CLASS_DISPLAY_VGA) || |
568 | if( (class == PCI_CLASS_DISPLAY_VGA) || |
555 | (class == PCI_CLASS_BRIDGE_HOST) || |
569 | (class == PCI_CLASS_BRIDGE_HOST) || |
556 | (class == PCI_CLASS_BRIDGE_ISA)) |
570 | (class == PCI_CLASS_BRIDGE_ISA)) |
557 | ret = 1; |
571 | ret = 1; |
558 | } |
572 | } |
559 | return ret; |
573 | return ret; |
560 | }; |
574 | }; |
561 | 575 | ||
562 | 576 | ||
563 | struct mtrr |
577 | struct mtrr |
564 | { |
578 | { |
565 | u64 base; |
579 | u64 base; |
566 | u64 mask; |
580 | u64 mask; |
567 | }; |
581 | }; |
568 | 582 | ||
569 | struct cpuinfo |
583 | struct cpuinfo |
570 | { |
584 | { |
571 | u64 caps; |
585 | u64 caps; |
572 | u64 def_mtrr; |
586 | u64 def_mtrr; |
573 | u64 mtrr_cap; |
587 | u64 mtrr_cap; |
574 | int var_mtrr_count; |
588 | int var_mtrr_count; |
575 | int fix_mtrr_count; |
589 | int fix_mtrr_count; |
576 | struct mtrr var_mtrr[9]; |
590 | struct mtrr var_mtrr[9]; |
577 | char model_name[64]; |
591 | char model_name[64]; |
578 | }; |
592 | }; |
579 | 593 | ||
580 | #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) |
594 | #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg)) |
581 | #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) |
595 | #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1) |
582 | 596 | ||
583 | #define MSR_MTRRdefType 0x000002ff |
597 | #define MSR_MTRRdefType 0x000002ff |
584 | 598 | ||
585 | #define IA32_MTRRCAP 0xFE |
599 | #define IA32_MTRRCAP 0xFE |
586 | #define IA32_CR_PAT_MSR 0x277 |
600 | #define IA32_CR_PAT_MSR 0x277 |
587 | 601 | ||
588 | #define PAT_TYPE_UC 0 |
602 | #define PAT_TYPE_UC 0 |
589 | #define PAT_TYPE_WC 1 |
603 | #define PAT_TYPE_WC 1 |
590 | #define PAT_TYPE_WB 6 |
604 | #define PAT_TYPE_WB 6 |
591 | #define PAT_TYPE_UCM 7 |
605 | #define PAT_TYPE_UCM 7 |
592 | 606 | ||
593 | 607 | ||
594 | #define MTRR_UC 0 |
608 | #define MTRR_UC 0 |
595 | #define MTRR_WC 1 |
609 | #define MTRR_WC 1 |
596 | #define MTRR_WB 6 |
610 | #define MTRR_WB 6 |
597 | 611 | ||
598 | static inline u64 read_msr(u32 msr) |
612 | static inline u64 read_msr(u32 msr) |
599 | { |
613 | { |
600 | union { |
614 | union { |
601 | u64 val; |
615 | u64 val; |
602 | struct { |
616 | struct { |
603 | u32 low; |
617 | u32 low; |
604 | u32 high; |
618 | u32 high; |
605 | }; |
619 | }; |
606 | }tmp; |
620 | }tmp; |
607 | 621 | ||
608 | asm volatile ( |
622 | asm volatile ( |
609 | "rdmsr" |
623 | "rdmsr" |
610 | : "=a" (tmp.low), "=d" (tmp.high) |
624 | : "=a" (tmp.low), "=d" (tmp.high) |
611 | : "c" (msr)); |
625 | : "c" (msr)); |
612 | return tmp.val; |
626 | return tmp.val; |
613 | } |
627 | } |
614 | 628 | ||
615 | static inline void write_msr(u32 msr, u64 val) |
629 | static inline void write_msr(u32 msr, u64 val) |
616 | { |
630 | { |
617 | union { |
631 | union { |
618 | u64 val; |
632 | u64 val; |
619 | struct { |
633 | struct { |
620 | u32 low; |
634 | u32 low; |
621 | u32 high; |
635 | u32 high; |
622 | }; |
636 | }; |
623 | }tmp; |
637 | }tmp; |
624 | 638 | ||
625 | tmp.val = val; |
639 | tmp.val = val; |
626 | 640 | ||
627 | asm volatile ( |
641 | asm volatile ( |
628 | "wrmsr" |
642 | "wrmsr" |
629 | :: "a" (tmp.low), "d" (tmp.high), "c" (msr)); |
643 | :: "a" (tmp.low), "d" (tmp.high), "c" (msr)); |
630 | } |
644 | } |
631 | 645 | ||
632 | #define SIZE_OR_MASK_BITS(n) (~((1ULL << ((n) - PAGE_SHIFT)) - 1)) |
646 | #define SIZE_OR_MASK_BITS(n) (~((1ULL << ((n) - PAGE_SHIFT)) - 1)) |
633 | 647 | ||
634 | static void set_mtrr(unsigned int reg, unsigned long base, |
648 | static void set_mtrr(unsigned int reg, unsigned long base, |
635 | unsigned long size, int type) |
649 | unsigned long size, int type) |
636 | { |
650 | { |
637 | unsigned int base_lo, base_hi, mask_lo, mask_hi; |
651 | unsigned int base_lo, base_hi, mask_lo, mask_hi; |
638 | u64 size_or_mask, size_and_mask; |
652 | u64 size_or_mask, size_and_mask; |
639 | 653 | ||
640 | size_or_mask = SIZE_OR_MASK_BITS(36); |
654 | size_or_mask = SIZE_OR_MASK_BITS(36); |
641 | size_and_mask = 0x00f00000; |
655 | size_and_mask = 0x00f00000; |
642 | 656 | ||
643 | if (size == 0) { |
657 | if (size == 0) { |
644 | /* |
658 | /* |
645 | * The invalid bit is kept in the mask, so we simply |
659 | * The invalid bit is kept in the mask, so we simply |
646 | * clear the relevant mask register to disable a range. |
660 | * clear the relevant mask register to disable a range. |
647 | */ |
661 | */ |
648 | native_write_msr(MTRRphysMask_MSR(reg), 0, 0); |
662 | native_write_msr(MTRRphysMask_MSR(reg), 0, 0); |
649 | } |
663 | } |
650 | else { |
664 | else { |
651 | base_lo = base << PAGE_SHIFT | type; |
665 | base_lo = base << PAGE_SHIFT | type; |
652 | base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT); |
666 | base_hi = (base & size_and_mask) >> (32 - PAGE_SHIFT); |
653 | mask_lo = -size << PAGE_SHIFT | 0x800; |
667 | mask_lo = -size << PAGE_SHIFT | 0x800; |
654 | mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT); |
668 | mask_hi = (-size & size_and_mask) >> (32 - PAGE_SHIFT); |
655 | 669 | ||
656 | native_write_msr(MTRRphysBase_MSR(reg), base_lo, base_hi); |
670 | native_write_msr(MTRRphysBase_MSR(reg), base_lo, base_hi); |
657 | native_write_msr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); |
671 | native_write_msr(MTRRphysMask_MSR(reg), mask_lo, mask_hi); |
658 | }; |
672 | }; |
659 | } |
673 | } |
660 | 674 | ||
661 | 675 | ||
662 | static u32 deftype_lo, deftype_hi; |
676 | static u32 deftype_lo, deftype_hi; |
663 | 677 | ||
664 | void cpu_detect1() |
678 | void cpu_detect1() |
665 | { |
679 | { |
666 | struct cpuinfo cpuinfo; |
680 | struct cpuinfo cpuinfo; |
667 | 681 | ||
668 | u32 junk, tfms, cap0, misc; |
682 | u32 junk, tfms, cap0, misc; |
669 | int i; |
683 | int i; |
670 | 684 | ||
671 | cpuid(0x00000001, &tfms, &misc, &junk, &cap0); |
685 | cpuid(0x00000001, &tfms, &misc, &junk, &cap0); |
672 | 686 | ||
673 | if (cap0 & (1<<19)) |
687 | if (cap0 & (1<<19)) |
674 | { |
688 | { |
675 | x86_clflush_size = ((misc >> 8) & 0xff) * 8; |
689 | x86_clflush_size = ((misc >> 8) & 0xff) * 8; |
676 | } |
690 | } |
677 | 691 | ||
678 | #if 0 |
692 | #if 0 |
679 | cpuid(0x80000002, (unsigned int*)&cpuinfo.model_name[0], (unsigned int*)&cpuinfo.model_name[4], |
693 | cpuid(0x80000002, (unsigned int*)&cpuinfo.model_name[0], (unsigned int*)&cpuinfo.model_name[4], |
680 | (unsigned int*)&cpuinfo.model_name[8], (unsigned int*)&cpuinfo.model_name[12]); |
694 | (unsigned int*)&cpuinfo.model_name[8], (unsigned int*)&cpuinfo.model_name[12]); |
681 | cpuid(0x80000003, (unsigned int*)&cpuinfo.model_name[16], (unsigned int*)&cpuinfo.model_name[20], |
695 | cpuid(0x80000003, (unsigned int*)&cpuinfo.model_name[16], (unsigned int*)&cpuinfo.model_name[20], |
682 | (unsigned int*)&cpuinfo.model_name[24], (unsigned int*)&cpuinfo.model_name[28]); |
696 | (unsigned int*)&cpuinfo.model_name[24], (unsigned int*)&cpuinfo.model_name[28]); |
683 | cpuid(0x80000004, (unsigned int*)&cpuinfo.model_name[32], (unsigned int*)&cpuinfo.model_name[36], |
697 | cpuid(0x80000004, (unsigned int*)&cpuinfo.model_name[32], (unsigned int*)&cpuinfo.model_name[36], |
684 | (unsigned int*)&cpuinfo.model_name[40], (unsigned int*)&cpuinfo.model_name[44]); |
698 | (unsigned int*)&cpuinfo.model_name[40], (unsigned int*)&cpuinfo.model_name[44]); |
685 | 699 | ||
686 | printf("\n%s\n\n",cpuinfo.model_name); |
700 | printf("\n%s\n\n",cpuinfo.model_name); |
687 | 701 | ||
688 | cpuinfo.def_mtrr = read_msr(MSR_MTRRdefType); |
702 | cpuinfo.def_mtrr = read_msr(MSR_MTRRdefType); |
689 | cpuinfo.mtrr_cap = read_msr(IA32_MTRRCAP); |
703 | cpuinfo.mtrr_cap = read_msr(IA32_MTRRCAP); |
690 | 704 | ||
691 | printf("MSR_MTRRdefType %016llx\n\n", cpuinfo.def_mtrr); |
705 | printf("MSR_MTRRdefType %016llx\n\n", cpuinfo.def_mtrr); |
692 | 706 | ||
693 | cpuinfo.var_mtrr_count = (u8_t)cpuinfo.mtrr_cap; |
707 | cpuinfo.var_mtrr_count = (u8_t)cpuinfo.mtrr_cap; |
694 | 708 | ||
695 | for(i = 0; i < cpuinfo.var_mtrr_count; i++) |
709 | for(i = 0; i < cpuinfo.var_mtrr_count; i++) |
696 | { |
710 | { |
697 | u64_t mtrr_base; |
711 | u64_t mtrr_base; |
698 | u64_t mtrr_mask; |
712 | u64_t mtrr_mask; |
699 | 713 | ||
700 | cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i)); |
714 | cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i)); |
701 | cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i)); |
715 | cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i)); |
702 | 716 | ||
703 | printf("MTRR_%d base: %016llx mask: %016llx\n", i, |
717 | printf("MTRR_%d base: %016llx mask: %016llx\n", i, |
704 | cpuinfo.var_mtrr[i].base, |
718 | cpuinfo.var_mtrr[i].base, |
705 | cpuinfo.var_mtrr[i].mask); |
719 | cpuinfo.var_mtrr[i].mask); |
706 | }; |
720 | }; |
707 | 721 | ||
708 | unsigned int cr0, cr3, cr4, eflags; |
722 | unsigned int cr0, cr3, cr4, eflags; |
709 | 723 | ||
710 | eflags = safe_cli(); |
724 | eflags = safe_cli(); |
711 | 725 | ||
712 | /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ |
726 | /* Enter the no-fill (CD=1, NW=0) cache mode and flush caches. */ |
713 | cr0 = read_cr0() | (1<<30); |
727 | cr0 = read_cr0() | (1<<30); |
714 | write_cr0(cr0); |
728 | write_cr0(cr0); |
715 | wbinvd(); |
729 | wbinvd(); |
716 | 730 | ||
717 | cr4 = read_cr4(); |
731 | cr4 = read_cr4(); |
718 | write_cr4(cr4 & ~(1<<7)); |
732 | write_cr4(cr4 & ~(1<<7)); |
719 | 733 | ||
720 | cr3 = read_cr3(); |
734 | cr3 = read_cr3(); |
721 | write_cr3(cr3); |
735 | write_cr3(cr3); |
722 | 736 | ||
723 | /* Save MTRR state */ |
737 | /* Save MTRR state */ |
724 | rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); |
738 | rdmsr(MSR_MTRRdefType, deftype_lo, deftype_hi); |
725 | 739 | ||
726 | /* Disable MTRRs, and set the default type to uncached */ |
740 | /* Disable MTRRs, and set the default type to uncached */ |
727 | native_write_msr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); |
741 | native_write_msr(MSR_MTRRdefType, deftype_lo & ~0xcff, deftype_hi); |
728 | wbinvd(); |
742 | wbinvd(); |
729 | 743 | ||
730 | i = 0; |
744 | i = 0; |
731 | set_mtrr(i++,0,0x80000000>>12,MTRR_WB); |
745 | set_mtrr(i++,0,0x80000000>>12,MTRR_WB); |
732 | set_mtrr(i++,0x80000000>>12,0x40000000>>12,MTRR_WB); |
746 | set_mtrr(i++,0x80000000>>12,0x40000000>>12,MTRR_WB); |
733 | set_mtrr(i++,0xC0000000>>12,0x20000000>>12,MTRR_WB); |
747 | set_mtrr(i++,0xC0000000>>12,0x20000000>>12,MTRR_WB); |
734 | set_mtrr(i++,0xdb800000>>12,0x00800000>>12,MTRR_UC); |
748 | set_mtrr(i++,0xdb800000>>12,0x00800000>>12,MTRR_UC); |
735 | set_mtrr(i++,0xdc000000>>12,0x04000000>>12,MTRR_UC); |
749 | set_mtrr(i++,0xdc000000>>12,0x04000000>>12,MTRR_UC); |
736 | set_mtrr(i++,0xE0000000>>12,0x10000000>>12,MTRR_WC); |
750 | set_mtrr(i++,0xE0000000>>12,0x10000000>>12,MTRR_WC); |
737 | 751 | ||
738 | for(; i < cpuinfo.var_mtrr_count; i++) |
752 | for(; i < cpuinfo.var_mtrr_count; i++) |
739 | set_mtrr(i,0,0,0); |
753 | set_mtrr(i,0,0,0); |
740 | 754 | ||
741 | write_cr3(cr3); |
755 | write_cr3(cr3); |
742 | 756 | ||
743 | /* Intel (P6) standard MTRRs */ |
757 | /* Intel (P6) standard MTRRs */ |
744 | native_write_msr(MSR_MTRRdefType, deftype_lo, deftype_hi); |
758 | native_write_msr(MSR_MTRRdefType, deftype_lo, deftype_hi); |
745 | 759 | ||
746 | /* Enable caches */ |
760 | /* Enable caches */ |
747 | write_cr0(read_cr0() & ~(1<<30)); |
761 | write_cr0(read_cr0() & ~(1<<30)); |
748 | 762 | ||
749 | /* Restore value of CR4 */ |
763 | /* Restore value of CR4 */ |
750 | write_cr4(cr4); |
764 | write_cr4(cr4); |
751 | 765 | ||
752 | safe_sti(eflags); |
766 | safe_sti(eflags); |
753 | 767 | ||
754 | printf("\nnew MTRR map\n\n"); |
768 | printf("\nnew MTRR map\n\n"); |
755 | 769 | ||
756 | for(i = 0; i < cpuinfo.var_mtrr_count; i++) |
770 | for(i = 0; i < cpuinfo.var_mtrr_count; i++) |
757 | { |
771 | { |
758 | u64_t mtrr_base; |
772 | u64_t mtrr_base; |
759 | u64_t mtrr_mask; |
773 | u64_t mtrr_mask; |
760 | 774 | ||
761 | cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i)); |
775 | cpuinfo.var_mtrr[i].base = read_msr(MTRRphysBase_MSR(i)); |
762 | cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i)); |
776 | cpuinfo.var_mtrr[i].mask = read_msr(MTRRphysMask_MSR(i)); |
763 | 777 | ||
764 | printf("MTRR_%d base: %016llx mask: %016llx\n", i, |
778 | printf("MTRR_%d base: %016llx mask: %016llx\n", i, |
765 | cpuinfo.var_mtrr[i].base, |
779 | cpuinfo.var_mtrr[i].base, |
766 | cpuinfo.var_mtrr[i].mask); |
780 | cpuinfo.var_mtrr[i].mask); |
767 | }; |
781 | }; |
768 | #endif |
782 | #endif |
769 | 783 | ||
770 | tsc_khz = (unsigned int)(GetCpuFreq()/1000); |
784 | tsc_khz = (unsigned int)(GetCpuFreq()/1000); |
771 | } |
785 | } |
772 | 786 | ||
773 | 787 | ||
774 | int get_driver_caps(hwcaps_t *caps) |
788 | int get_driver_caps(hwcaps_t *caps) |
775 | { |
789 | { |
776 | int ret = 0; |
790 | int ret = 0; |
777 | 791 | ||
778 | switch(caps->idx) |
792 | switch(caps->idx) |
779 | { |
793 | { |
780 | case 0: |
794 | case 0: |
781 | caps->opt[0] = 0; |
795 | caps->opt[0] = 0; |
782 | caps->opt[1] = 0; |
796 | caps->opt[1] = 0; |
783 | break; |
797 | break; |
784 | 798 | ||
785 | case 1: |
799 | case 1: |
786 | caps->cap1.max_tex_width = 4096; |
800 | caps->cap1.max_tex_width = 4096; |
787 | caps->cap1.max_tex_height = 4096; |
801 | caps->cap1.max_tex_height = 4096; |
788 | break; |
802 | break; |
789 | default: |
803 | default: |
790 | ret = 1; |
804 | ret = 1; |
791 | }; |
805 | }; |
792 | caps->idx = 1; |
806 | caps->idx = 1; |
793 | return ret; |
807 | return ret; |
794 | } |
808 | } |
795 | 809 | ||
796 | 810 | ||
797 | void get_pci_info(struct pci_device *dev) |
811 | void get_pci_info(struct pci_device *dev) |
798 | { |
812 | { |
799 | struct pci_dev *pdev = main_device->pdev; |
813 | struct pci_dev *pdev = main_device->pdev; |
800 | 814 | ||
801 | memset(dev, sizeof(*dev), 0); |
815 | memset(dev, sizeof(*dev), 0); |
802 | 816 | ||
803 | dev->domain = 0; |
817 | dev->domain = 0; |
804 | dev->bus = pdev->busnr; |
818 | dev->bus = pdev->busnr; |
805 | dev->dev = pdev->devfn >> 3; |
819 | dev->dev = pdev->devfn >> 3; |
806 | dev->func = pdev->devfn & 7; |
820 | dev->func = pdev->devfn & 7; |
807 | dev->vendor_id = pdev->vendor; |
821 | dev->vendor_id = pdev->vendor; |
808 | dev->device_id = pdev->device; |
822 | dev->device_id = pdev->device; |
809 | dev->revision = pdev->revision; |
823 | dev->revision = pdev->revision; |
810 | }; |
824 | }; |
811 | 825 | ||
812 | 826 | ||
813 | 827 | ||
814 | char *strstr(const char *cs, const char *ct); |
828 | char *strstr(const char *cs, const char *ct); |
815 | 829 | ||
816 | static int my_atoi(char **cmd) |
830 | static int my_atoi(char **cmd) |
817 | { |
831 | { |
818 | char* p = *cmd; |
832 | char* p = *cmd; |
819 | int val = 0; |
833 | int val = 0; |
820 | int sign = 1; |
834 | int sign = 1; |
821 | 835 | ||
822 | if(*p == '-') |
836 | if(*p == '-') |
823 | { |
837 | { |
824 | sign = -1; |
838 | sign = -1; |
825 | p++; |
839 | p++; |
826 | }; |
840 | }; |
827 | 841 | ||
828 | for (;; *p++) { |
842 | for (;; *p++) { |
829 | switch (*p) { |
843 | switch (*p) { |
830 | case '0' ... '9': |
844 | case '0' ... '9': |
831 | val = 10*val+(*p-'0'); |
845 | val = 10*val+(*p-'0'); |
832 | break; |
846 | break; |
833 | default: |
847 | default: |
834 | *cmd = p; |
848 | *cmd = p; |
835 | return val*sign; |
849 | return val*sign; |
836 | } |
850 | } |
837 | } |
851 | } |
838 | } |
852 | } |
839 | 853 | ||
840 | static char* parse_mode(char *p, videomode_t *mode) |
854 | static char* parse_mode(char *p, videomode_t *mode) |
841 | { |
855 | { |
842 | char c; |
856 | char c; |
843 | 857 | ||
844 | while( (c = *p++) == ' '); |
858 | while( (c = *p++) == ' '); |
845 | 859 | ||
846 | if( c ) |
860 | if( c ) |
847 | { |
861 | { |
848 | p--; |
862 | p--; |
849 | 863 | ||
850 | mode->width = my_atoi(&p); |
864 | mode->width = my_atoi(&p); |
851 | if(*p == 'x') p++; |
865 | if(*p == 'x') p++; |
852 | 866 | ||
853 | mode->height = my_atoi(&p); |
867 | mode->height = my_atoi(&p); |
854 | if(*p == 'x') p++; |
868 | if(*p == 'x') p++; |
855 | 869 | ||
856 | mode->bpp = 32; |
870 | mode->bpp = 32; |
857 | 871 | ||
858 | mode->freq = my_atoi(&p); |
872 | mode->freq = my_atoi(&p); |
859 | 873 | ||
860 | if( mode->freq == 0 ) |
874 | if( mode->freq == 0 ) |
861 | mode->freq = 60; |
875 | mode->freq = 60; |
862 | } |
876 | } |
863 | 877 | ||
864 | return p; |
878 | return p; |
865 | };>30)); |
879 | };>30)); |
866 | 880 | ||
867 | ><30)); |
881 | ><30)); |
868 | 882 | ||
869 | >>7)); |
883 | >>7)); |
870 | 884 | ||
871 | ><7)); |
885 | ><7)); |
872 | 886 | ||
873 | >30); |
887 | >30); |
874 | ><30); |
888 | ><30); |
875 | >>19)) |
889 | >>19)) |
876 | ><19)) |
890 | ><19)) |
877 | >><>><>><>><>-1,0,1>-1,0-7> |
891 | >><>><>><>><>-1,0,1>-1,0-7> |