Changeset 43364 in vbox for trunk/src/VBox/Additions/haiku/VBoxVideo/driver
- Timestamp:
- Sep 20, 2012 12:12:09 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp
r43363 r43364 66 66 #undef TRACE 67 67 #ifdef ENABLE_DEBUG_TRACE 68 # 68 #define TRACE(x...) dprintf("VBoxVideo: " x) 69 69 #else 70 # 70 #define TRACE(x...) ; 71 71 #endif 72 72 … … 75 75 extern "C" status_t vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type); 76 76 77 struct Benaphore { 78 sem_id sem; 79 int32 count; 80 81 status_t Init(const char* name) 82 { 83 count = 0; 84 sem = create_sem(0, name); 85 return sem < 0 ? sem : B_OK; 86 } 87 88 status_t Acquire() 89 { 90 if (atomic_add(&count, 1) > 0) 91 return acquire_sem(sem); 92 return B_OK; 93 } 94 95 status_t Release() 96 { 97 if (atomic_add(&count, -1) > 1) 98 return release_sem(sem); 99 return B_OK; 100 } 101 102 void Delete() { delete_sem(sem); } 77 struct Benaphore 78 { 79 sem_id sem; 80 int32 count; 81 82 status_t Init(const char *name) 83 { 84 count = 0; 85 sem = create_sem(0, name); 86 return sem < 0 ? sem : B_OK; 87 } 88 89 status_t Acquire() 90 { 91 if (atomic_add(&count, 1) > 0) 92 return acquire_sem(sem); 93 return B_OK; 94 } 95 96 status_t Release() 97 { 98 if (atomic_add(&count, -1) > 1) 99 return release_sem(sem); 100 return B_OK; 101 } 102 103 void Delete() 104 { 105 delete_sem(sem); 106 } 103 107 }; 104 108 105 struct DeviceInfo { 106 uint32 openCount; // count of how many times device has been opened 107 uint32 flags; 108 area_id sharedArea; // area shared between driver and all accelerants 109 SharedInfo* sharedInfo; // pointer to shared info area memory 110 pci_info pciInfo; // copy of pci info for this device 111 char name[B_OS_NAME_LENGTH]; // name of device 109 struct DeviceInfo 110 { 111 uint32 openCount; // count of how many times device has been opened 112 uint32 flags; // device flags 113 area_id sharedArea; // area shared between driver and all accelerants 114 SharedInfo *sharedInfo; // pointer to shared info area memory 115 pci_info pciInfo; // copy of pci info for this device 116 char name[B_OS_NAME_LENGTH]; // name of device 112 117 }; 113 118 114 119 // at most one virtual video card ever appears, no reason for this to be an array 115 120 static DeviceInfo gDeviceInfo; 116 static char * gDeviceNames[2] = {gDeviceInfo.name, NULL};121 static char *gDeviceNames[2] = { gDeviceInfo.name, NULL }; 117 122 static bool gCanHasDevice = false; // is the device present? 118 123 static Benaphore gLock; 119 static pci_module_info *gPCI;120 121 status_t device_open(const char * name, uint32 flags, void**cookie);122 status_t device_close(void *dev);123 status_t device_free(void *dev);124 status_t device_read(void * dev, off_t pos, void* buf, size_t*len);125 status_t device_write(void * dev, off_t pos, const void* buf, size_t*len);126 status_t device_ioctl(void * dev, uint32 msg, void*buf, size_t len);124 static pci_module_info *gPCI; 125 126 status_t device_open(const char *name, uint32 flags, void **cookie); 127 status_t device_close(void *dev); 128 status_t device_free(void *dev); 129 status_t device_read(void *dev, off_t pos, void *buf, size_t *len); 130 status_t device_write(void *dev, off_t pos, const void *buf, size_t *len); 131 status_t device_ioctl(void *dev, uint32 msg, void *buf, size_t len); 127 132 static uint32 get_color_space_for_depth(uint32 depth); 128 133 129 static device_hooks gDeviceHooks = { 130 device_open, // open 131 device_close, // close 132 device_free, // free 133 device_ioctl, // control 134 device_read, // read 135 device_write, // write 136 NULL, // select 137 NULL, // deselect 138 NULL, // read_pages 139 NULL // write_pages 134 static device_hooks gDeviceHooks = 135 { 136 device_open, // open 137 device_close, // close 138 device_free, // free 139 device_ioctl, // control 140 device_read, // read 141 device_write, // write 142 NULL, // select 143 NULL, // deselect 144 NULL, // read_pages 145 NULL // write_pages 140 146 }; 141 147 142 148 status_t init_hardware() 143 149 { 144 TRACE("init_hardware\n"); 145 146 if (get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest) != B_OK) { 147 dprintf("get_module(%s) failed\n", VBOXGUEST_MODULE_NAME); 148 return B_ERROR; 149 } 150 151 if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI) != B_OK) { 152 dprintf("get_module(%s) failed\n", B_PCI_MODULE_NAME); 153 return B_ERROR; 154 } 155 156 return B_OK; 150 TRACE("init_hardware\n"); 151 152 if (get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest) != B_OK) 153 { 154 dprintf("get_module(%s) failed\n", VBOXGUEST_MODULE_NAME); 155 return B_ERROR; 156 } 157 158 if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI) != B_OK) 159 { 160 dprintf("get_module(%s) failed\n", B_PCI_MODULE_NAME); 161 return B_ERROR; 162 } 163 164 return B_OK; 157 165 } 158 166 159 167 status_t init_driver() 160 168 { 161 TRACE("init_driver\n"); 162 163 gLock.Init("VBoxVideo driver lock"); 164 165 uint32 pciIndex = 0; 166 167 while (gPCI->get_nth_pci_info(pciIndex, &gDeviceInfo.pciInfo) == B_OK) { 168 if (gDeviceInfo.pciInfo.vendor_id == VENDOR_ID && gDeviceInfo.pciInfo.device_id == DEVICE_ID) { 169 sprintf(gDeviceInfo.name, "graphics/" DEVICE_FORMAT, 170 gDeviceInfo.pciInfo.vendor_id, gDeviceInfo.pciInfo.device_id, 171 gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function); 172 TRACE("found device %s\n", gDeviceInfo.name); 173 174 gCanHasDevice = true; 175 gDeviceInfo.openCount = 0; 176 177 size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7; 178 gDeviceInfo.sharedArea = create_area("vboxvideo shared info", 179 (void**)&gDeviceInfo.sharedInfo, B_ANY_KERNEL_ADDRESS, 180 ROUND_TO_PAGE_SIZE(sharedSize), B_FULL_LOCK, 181 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA); 182 183 uint16_t width, height, vwidth, bpp, flags; 184 VBoxVideoGetModeRegisters(&width, &height, &vwidth, &bpp, &flags); 185 186 gDeviceInfo.sharedInfo->currentMode.space = get_color_space_for_depth(bpp); 187 gDeviceInfo.sharedInfo->currentMode.virtual_width = width; 188 gDeviceInfo.sharedInfo->currentMode.virtual_height = height; 189 gDeviceInfo.sharedInfo->currentMode.h_display_start = 0; 190 gDeviceInfo.sharedInfo->currentMode.v_display_start = 0; 191 gDeviceInfo.sharedInfo->currentMode.flags = 0; 192 gDeviceInfo.sharedInfo->currentMode.timing.h_display = width; 193 gDeviceInfo.sharedInfo->currentMode.timing.v_display = height; 194 // not used, but this makes a reasonable-sounding refresh rate show in screen prefs: 195 gDeviceInfo.sharedInfo->currentMode.timing.h_total = 1000; 196 gDeviceInfo.sharedInfo->currentMode.timing.v_total = 1; 197 gDeviceInfo.sharedInfo->currentMode.timing.pixel_clock = 850; 198 199 // map the PCI memory space 200 uint32 command_reg = gPCI->read_pci_config(gDeviceInfo.pciInfo.bus, 201 gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function, PCI_command, 2); 202 command_reg |= PCI_command_io | PCI_command_memory | PCI_command_master; 203 gPCI->write_pci_config(gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, 204 gDeviceInfo.pciInfo.function, PCI_command, 2, command_reg); 205 206 gDeviceInfo.sharedInfo->framebufferArea = 207 map_physical_memory("vboxvideo framebuffer", (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], 208 gDeviceInfo.pciInfo.u.h0.base_register_sizes[0], B_ANY_KERNEL_BLOCK_ADDRESS, 209 B_READ_AREA | B_WRITE_AREA, &(gDeviceInfo.sharedInfo->framebuffer)); 210 vm_set_area_memory_type(gDeviceInfo.sharedInfo->framebufferArea, 211 (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], B_MTR_WC); 212 213 break; 214 } 215 216 pciIndex++; 217 } 218 219 return B_OK; 220 } 169 TRACE("init_driver\n"); 170 171 gLock.Init("VBoxVideo driver lock"); 172 173 uint32 pciIndex = 0; 174 175 while (gPCI->get_nth_pci_info(pciIndex, &gDeviceInfo.pciInfo) == B_OK) 176 { 177 if (gDeviceInfo.pciInfo.vendor_id == VENDOR_ID && gDeviceInfo.pciInfo.device_id == DEVICE_ID) 178 { 179 sprintf(gDeviceInfo.name, "graphics/" DEVICE_FORMAT, 180 gDeviceInfo.pciInfo.vendor_id, gDeviceInfo.pciInfo.device_id, 181 gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function); 182 TRACE("found device %s\n", gDeviceInfo.name); 183 184 gCanHasDevice = true; 185 gDeviceInfo.openCount = 0; 186 187 size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7; 188 gDeviceInfo.sharedArea = create_area("vboxvideo shared info", 189 (void **)&gDeviceInfo.sharedInfo, B_ANY_KERNEL_ADDRESS, 190 ROUND_TO_PAGE_SIZE(sharedSize), B_FULL_LOCK, 191 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA); 192 193 uint16_t width, height, vwidth, bpp, flags; 194 VBoxVideoGetModeRegisters(&width, &height, &vwidth, &bpp, &flags); 195 196 gDeviceInfo.sharedInfo->currentMode.space = get_color_space_for_depth(bpp); 197 gDeviceInfo.sharedInfo->currentMode.virtual_width = width; 198 gDeviceInfo.sharedInfo->currentMode.virtual_height = height; 199 gDeviceInfo.sharedInfo->currentMode.h_display_start = 0; 200 gDeviceInfo.sharedInfo->currentMode.v_display_start = 0; 201 gDeviceInfo.sharedInfo->currentMode.flags = 0; 202 gDeviceInfo.sharedInfo->currentMode.timing.h_display = width; 203 gDeviceInfo.sharedInfo->currentMode.timing.v_display = height; 204 // not used, but this makes a reasonable-sounding refresh rate show in screen prefs: 205 gDeviceInfo.sharedInfo->currentMode.timing.h_total = 1000; 206 gDeviceInfo.sharedInfo->currentMode.timing.v_total = 1; 207 gDeviceInfo.sharedInfo->currentMode.timing.pixel_clock = 850; 208 209 // map the PCI memory space 210 uint32 command_reg = gPCI->read_pci_config(gDeviceInfo.pciInfo.bus, 211 gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function, PCI_command, 2); 212 command_reg |= PCI_command_io | PCI_command_memory | PCI_command_master; 213 gPCI->write_pci_config(gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, 214 gDeviceInfo.pciInfo.function, PCI_command, 2, command_reg); 215 216 gDeviceInfo.sharedInfo->framebufferArea = map_physical_memory("vboxvideo framebuffer", 217 (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], 218 gDeviceInfo.pciInfo.u.h0.base_register_sizes[0], B_ANY_KERNEL_BLOCK_ADDRESS, 219 B_READ_AREA | B_WRITE_AREA, &(gDeviceInfo.sharedInfo->framebuffer)); 220 vm_set_area_memory_type(gDeviceInfo.sharedInfo->framebufferArea, 221 (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], B_MTR_WC); 222 break; 223 } 224 225 pciIndex++; 226 } 227 228 return B_OK; 229 } 230 221 231 222 232 const char** publish_devices() 223 233 { 224 TRACE("publish_devices\n"); 225 if (gCanHasDevice) { 226 return (const char**)gDeviceNames; 227 } 228 else { 229 return NULL; 230 } 231 } 232 233 device_hooks* find_device(const char* name) 234 { 235 TRACE("find_device\n"); 236 if (gCanHasDevice && strcmp(name, gDeviceInfo.name) == 0) { 237 return &gDeviceHooks; 238 } 239 else { 240 return NULL; 241 } 242 } 234 TRACE("publish_devices\n"); 235 if (gCanHasDevice) 236 return (const char **)gDeviceNames; 237 return NULL; 238 } 239 240 241 device_hooks* find_device(const char *name) 242 { 243 TRACE("find_device\n"); 244 if (gCanHasDevice && strcmp(name, gDeviceInfo.name) == 0) 245 return &gDeviceHooks; 246 247 return NULL; 248 } 249 243 250 244 251 void uninit_driver() 245 252 { 246 TRACE("uninit_driver\n"); 247 gLock.Delete(); 248 put_module(VBOXGUEST_MODULE_NAME); 249 } 250 251 status_t device_open(const char* name, uint32 flags, void** cookie) 252 { 253 TRACE("device_open\n"); 254 255 if (!gCanHasDevice || strcmp(name, gDeviceInfo.name) != 0) 256 return B_BAD_VALUE; 257 258 // TODO init device! 259 260 *cookie = (void*)&gDeviceInfo; 261 262 return B_OK; 263 } 264 265 status_t device_close(void* dev) 266 { 267 TRACE("device_close\n"); 268 return B_ERROR; 269 } 270 271 status_t device_free(void* dev) 272 { 273 TRACE("device_free\n"); 274 275 DeviceInfo& di = *(DeviceInfo*)dev; 276 gLock.Acquire(); 277 278 if (di.openCount <= 1) { 279 // TODO deinit device! 280 281 delete_area(di.sharedArea); 282 di.sharedArea = -1; 283 di.sharedInfo = NULL; 284 } 285 286 if (di.openCount > 0) 287 di.openCount--; 288 289 gLock.Release(); 290 291 return B_OK; 292 } 293 294 status_t device_read(void* dev, off_t pos, void* buf, size_t* len) 295 { 296 TRACE("device_read\n"); 297 return B_NOT_ALLOWED; 298 } 299 300 status_t device_write(void* dev, off_t pos, const void* buf, size_t* len) 301 { 302 TRACE("device_write\n"); 303 return B_NOT_ALLOWED; 304 } 305 306 status_t device_ioctl(void* cookie, uint32 msg, void* buf, size_t len) 307 { 308 TRACE("device_ioctl\n"); 309 310 DeviceInfo* dev = (DeviceInfo*)cookie; 311 312 switch (msg) { 313 case B_GET_ACCELERANT_SIGNATURE: 314 strcpy((char*)buf, "vboxvideo.accelerant"); 315 return B_OK; 316 317 case VBOXVIDEO_GET_PRIVATE_DATA: 318 return user_memcpy(buf, &dev->sharedArea, sizeof(area_id)); 319 320 case VBOXVIDEO_GET_DEVICE_NAME: 321 if (user_strlcpy((char*)buf, gDeviceInfo.name, len) < B_OK) 322 return B_BAD_ADDRESS; 323 else 324 return B_OK; 325 326 case VBOXVIDEO_SET_DISPLAY_MODE: { 327 display_mode* mode = (display_mode*)buf; 328 VBoxVideoSetModeRegisters(mode->timing.h_display, mode->timing.v_display, 329 mode->timing.h_display, get_depth_for_color_space(mode->space), 0, 0, 0); 330 gDeviceInfo.sharedInfo->currentMode = *mode; 331 return B_OK; 332 } 333 default: 334 return B_BAD_VALUE; 335 } 336 337 } 253 TRACE("uninit_driver\n"); 254 gLock.Delete(); 255 put_module(VBOXGUEST_MODULE_NAME); 256 } 257 258 status_t device_open(const char *name, uint32 flags, void **cookie) 259 { 260 TRACE("device_open\n"); 261 262 if (!gCanHasDevice || strcmp(name, gDeviceInfo.name) != 0) 263 return B_BAD_VALUE; 264 265 // TODO init device! 266 267 *cookie = (void *)&gDeviceInfo; 268 return B_OK; 269 } 270 271 272 status_t device_close(void *dev) 273 { 274 TRACE("device_close\n"); 275 return B_ERROR; 276 } 277 278 279 status_t device_free(void *dev) 280 { 281 TRACE("device_free\n"); 282 283 DeviceInfo& di = *(DeviceInfo *)dev; 284 gLock.Acquire(); 285 286 if (di.openCount <= 1) 287 { 288 // TODO deinit device! 289 delete_area(di.sharedArea); 290 di.sharedArea = -1; 291 di.sharedInfo = NULL; 292 } 293 294 if (di.openCount > 0) 295 di.openCount--; 296 297 gLock.Release(); 298 299 return B_OK; 300 } 301 302 303 status_t device_read(void *dev, off_t pos, void *buf, size_t *len) 304 { 305 TRACE("device_read\n"); 306 return B_NOT_ALLOWED; 307 } 308 309 310 status_t device_write(void *dev, off_t pos, const void *buf, size_t *len) 311 { 312 TRACE("device_write\n"); 313 return B_NOT_ALLOWED; 314 } 315 316 317 status_t device_ioctl(void *cookie, uint32 msg, void *buf, size_t len) 318 { 319 TRACE("device_ioctl\n"); 320 321 DeviceInfo *dev = (DeviceInfo *)cookie; 322 323 switch (msg) 324 { 325 case B_GET_ACCELERANT_SIGNATURE: 326 strcpy((char *)buf, "vboxvideo.accelerant"); 327 return B_OK; 328 329 case VBOXVIDEO_GET_PRIVATE_DATA: 330 return user_memcpy(buf, &dev->sharedArea, sizeof(area_id)); 331 332 case VBOXVIDEO_GET_DEVICE_NAME: 333 if (user_strlcpy((char *)buf, gDeviceInfo.name, len) < B_OK) 334 return B_BAD_ADDRESS; 335 else 336 return B_OK; 337 338 case VBOXVIDEO_SET_DISPLAY_MODE: 339 { 340 display_mode *mode = (display_mode *)buf; 341 VBoxVideoSetModeRegisters(mode->timing.h_display, mode->timing.v_display, 342 mode->timing.h_display, get_depth_for_color_space(mode->space), 0, 0, 0); 343 gDeviceInfo.sharedInfo->currentMode = *mode; 344 return B_OK; 345 } 346 default: 347 return B_BAD_VALUE; 348 } 349 350 } 351
Note:
See TracChangeset
for help on using the changeset viewer.