1 /* 2 * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "vesa_private.h" 8 9 #include <string.h> 10 11 #include <boot_item.h> 12 #include <frame_buffer_console.h> 13 #include <util/kernel_cpp.h> 14 15 #include "driver.h" 16 #include "utility.h" 17 #include "vesa_info.h" 18 19 20 class PhysicalMemoryMapper { 21 public: 22 PhysicalMemoryMapper(); 23 ~PhysicalMemoryMapper(); 24 25 area_id Map(const char *name, void *physicalAddress, size_t numBytes, 26 uint32 spec, uint32 protection, void **virtualAddress); 27 status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; } 28 void Keep(); 29 30 private: 31 area_id fArea; 32 }; 33 34 35 PhysicalMemoryMapper::PhysicalMemoryMapper() 36 : 37 fArea(-1) 38 { 39 } 40 41 42 PhysicalMemoryMapper::~PhysicalMemoryMapper() 43 { 44 if (fArea >= B_OK) 45 delete_area(fArea); 46 } 47 48 49 area_id 50 PhysicalMemoryMapper::Map(const char *name, void *physicalAddress, 51 size_t numBytes, uint32 spec, uint32 protection, void **virtualAddress) 52 { 53 fArea = map_physical_memory(name, physicalAddress, numBytes, spec, 54 protection, virtualAddress); 55 return fArea; 56 } 57 58 59 void 60 PhysicalMemoryMapper::Keep() 61 { 62 fArea = -1; 63 } 64 65 66 // #pragma mark - 67 68 69 static uint32 70 get_color_space_for_depth(uint32 depth) 71 { 72 switch (depth) { 73 case 4: 74 return B_GRAY8; 75 // the app_server is smart enough to translate this to VGA mode 76 case 8: 77 return B_CMAP8; 78 case 15: 79 return B_RGB15; 80 case 16: 81 return B_RGB16; 82 case 24: 83 return B_RGB24; 84 case 32: 85 return B_RGB32; 86 } 87 88 return 0; 89 } 90 91 92 // #pragma mark - 93 94 95 status_t 96 vesa_init(vesa_info &info) 97 { 98 frame_buffer_boot_info *bufferInfo 99 = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO, NULL); 100 if (bufferInfo == NULL) 101 return B_ERROR; 102 103 size_t modesSize = 0; 104 vesa_mode *modes = (vesa_mode *)get_boot_item(VESA_MODES_BOOT_INFO, 105 &modesSize); 106 107 size_t sharedSize = (sizeof(vesa_shared_info) + 7) & ~7; 108 109 info.shared_area = create_area("vesa shared info", 110 (void **)&info.shared_info, B_ANY_KERNEL_ADDRESS, 111 ROUND_TO_PAGE_SIZE(sharedSize + modesSize), B_FULL_LOCK, 112 B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA); 113 if (info.shared_area < B_OK) 114 return info.shared_area; 115 116 vesa_shared_info &sharedInfo = *info.shared_info; 117 118 memset(/*(void *)*/&sharedInfo, 0, sizeof(vesa_shared_info)); 119 120 if (modes != NULL) { 121 sharedInfo.vesa_mode_offset = sharedSize; 122 sharedInfo.vesa_mode_count = modesSize / sizeof(vesa_mode); 123 124 memcpy((uint8*)&sharedInfo + sharedSize, modes, modesSize); 125 } 126 127 sharedInfo.frame_buffer_area = bufferInfo->area; 128 sharedInfo.frame_buffer = (uint8 *)bufferInfo->frame_buffer; 129 130 sharedInfo.current_mode.virtual_width = bufferInfo->width; 131 sharedInfo.current_mode.virtual_height = bufferInfo->height; 132 sharedInfo.current_mode.space = get_color_space_for_depth( 133 bufferInfo->depth); 134 sharedInfo.bytes_per_row = bufferInfo->bytes_per_row; 135 136 physical_entry mapping; 137 get_memory_map((void *)sharedInfo.frame_buffer, B_PAGE_SIZE, 138 &mapping, 1); 139 sharedInfo.physical_frame_buffer = (uint8 *)mapping.address; 140 141 dprintf(DEVICE_NAME ": vesa_init() completed successfully!\n"); 142 return B_OK; 143 } 144 145 146 void 147 vesa_uninit(vesa_info &info) 148 { 149 dprintf(DEVICE_NAME": vesa_uninit()\n"); 150 151 delete_area(info.shared_info->frame_buffer_area); 152 delete_area(info.shared_area); 153 } 154 155