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