Changes in boot/genarch/ofw.c [fd375a8d:e0565005] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/genarch/ofw.c
rfd375a8d re0565005 32 32 #include <asm.h> 33 33 #include <types.h> 34 #include <string.h> 35 36 #define RED(i) (((i) >> 5) & ((1 << 3) - 1)) 37 #define GREEN(i) (((i) >> 3) & ((1 << 2) - 1)) 38 #define BLUE(i) ((i) & ((1 << 3) - 1)) 39 #define CLIP(i) ((i) <= 255 ? (i) : 255) 34 40 35 41 uintptr_t ofw_cif; … … 41 47 ihandle ofw_memory_prop; 42 48 phandle ofw_memory; 43 phandle ofw_aliases;44 49 45 50 void ofw_init(void) … … 69 74 halt(); 70 75 } 71 76 72 77 ofw_memory = ofw_find_device("/memory"); 73 78 if (ofw_memory == -1) { … … 75 80 halt(); 76 81 } 77 78 ofw_aliases = ofw_find_device("/aliases");79 if (ofw_aliases == -1) {80 puts("\r\nError: Unable to find /aliases device, halted.\r\n");81 halt();82 }83 82 } 84 83 85 84 /** Perform a call to OpenFirmware client interface. 86 85 * 87 * @param service String identifying the service requested. 88 * @param nargs Number of input arguments. 89 * @param nret Number of output arguments. This includes the return 90 * value. 91 * @param rets Buffer for output arguments or NULL. The buffer must 92 * accommodate nret - 1 items. 93 * 94 * @return Return value returned by the client interface. 86 * @param service String identifying the service requested. 87 * @param nargs Number of input arguments. 88 * @param nret Number of output arguments. This includes the return 89 * value. 90 * @param rets Buffer for output arguments or NULL. The buffer must 91 * accommodate nret - 1 items. 92 * 93 * @return Return value returned by the client interface. 94 * 95 95 */ 96 96 unsigned long … … 127 127 } 128 128 129 int 130 ofw_get_property(const phandle device, const char *name, void *buf, 129 int ofw_get_property(const phandle device, const char *name, void *buf, 131 130 const int buflen) 132 131 { … … 161 160 } 162 161 163 164 162 unsigned int ofw_get_size_cells(const phandle device) 165 163 { … … 221 219 } 222 220 223 void *ofw_claim_virt(const void *virt, const int len)221 void *ofw_claim_virt(const void *virt, const unsigned int len) 224 222 { 225 223 ofw_arg_t retaddr; … … 234 232 } 235 233 236 void *ofw_claim_phys(const void *phys, const int len) 237 { 238 ofw_arg_t retaddr[2]; 239 int shift; 240 234 static void *ofw_claim_phys_internal(const void *phys, const unsigned int len, const unsigned int alignment) 235 { 236 /* 237 * Note that the return value check will help 238 * us to discover conflicts between OpenFirmware 239 * allocations and our use of physical memory. 240 * It is better to detect collisions here 241 * than to cope with weird errors later. 242 * 243 * So this is really not to make the loader 244 * more generic; it is here for debugging 245 * purposes. 246 */ 247 241 248 if (sizeof(unative_t) == 8) { 242 shift = 32; 249 ofw_arg_t retaddr[2]; 250 int shift = 32; 251 243 252 if (ofw_call("call-method", 6, 3, retaddr, "claim", 244 ofw_memory_prop, 0, len, ((uintptr_t) phys) >> shift,253 ofw_memory_prop, alignment, len, ((uintptr_t) phys) >> shift, 245 254 ((uintptr_t) phys) & ((uint32_t) -1)) != 0) { 246 /*247 * Note that this will help us to discover248 * conflicts between OpenFirmware allocations249 * and our use of physical memory.250 * It is better to detect collisions here251 * than to cope with weird errors later.252 *253 * So this is really not to make the loader254 * more generic; it is here for debugging255 * purposes.256 */257 255 puts("Error: memory method claim() failed, halting.\n"); 258 256 halt(); 259 257 } 258 259 return (void *) ((retaddr[0] << shift) | retaddr[1]); 260 260 } else { 261 shift = 0; 262 /* 263 * FIXME: the number of arguments is probably different... 264 */ 265 puts("Error: 32-bit ofw_claim_phys not implemented.\n"); 266 halt(); 267 } 268 269 return (void *) ((retaddr[0] << shift) | retaddr[1]); 270 } 271 272 int ofw_map(const void *phys, const void *virt, const int size, const int mode) 261 ofw_arg_t retaddr[1]; 262 263 if (ofw_call("call-method", 5, 2, retaddr, "claim", 264 ofw_memory_prop, alignment, len, (uintptr_t) phys) != 0) { 265 puts("Error: memory method claim() failed, halting.\n"); 266 halt(); 267 } 268 269 return (void *) retaddr[0]; 270 } 271 } 272 273 void *ofw_claim_phys(const void *phys, const unsigned int len) 274 { 275 return ofw_claim_phys_internal(phys, len, 0); 276 } 277 278 void *ofw_claim_phys_any(const unsigned int len, const unsigned int alignment) 279 { 280 return ofw_claim_phys_internal(NULL, len, alignment); 281 } 282 283 int ofw_map(const void *phys, const void *virt, const unsigned int size, const int mode) 273 284 { 274 285 uintptr_t phys_hi, phys_lo; … … 314 325 315 326 /* 316 317 318 319 320 327 * This is a hot fix of the issue which occurs on machines 328 * where there are holes in the physical memory (such as 329 * SunBlade 1500). Should we detect a hole in the physical 330 * memory, we will ignore any memory detected behind 331 * the hole and pretend the hole does not exist. 321 332 */ 322 333 if ((map->count > 0) && (map->zones[map->count - 1].start + … … 335 346 } 336 347 337 int ofw_screen(screen_t *screen) 338 { 339 char device_name[BUF_SIZE]; 340 uint32_t virtaddr; 341 342 if (ofw_get_property(ofw_aliases, "screen", device_name, 343 sizeof(device_name)) <= 0) 344 return false; 345 346 phandle device = ofw_find_device(device_name); 347 if (device == -1) 348 return false; 349 350 if (ofw_get_property(device, "address", &virtaddr, 351 sizeof(virtaddr)) <= 0) 352 return false; 353 354 screen->addr = (void *) ((uintptr_t) virtaddr); 355 356 if (ofw_get_property(device, "width", &screen->width, 357 sizeof(screen->width)) <= 0) 358 return false; 359 360 if (ofw_get_property(device, "height", &screen->height, 361 sizeof(screen->height)) <= 0) 362 return false; 363 364 if (ofw_get_property(device, "depth", &screen->bpp, 365 sizeof(screen->bpp)) <= 0) 366 return false; 367 368 if (ofw_get_property(device, "linebytes", &screen->scanline, 369 sizeof(screen->scanline)) <= 0) 370 return false; 371 372 return true; 373 } 374 375 #define RED(i) (((i) >> 5) & ((1 << 3) - 1)) 376 #define GREEN(i) (((i) >> 3) & ((1 << 2) - 1)) 377 #define BLUE(i) ((i) & ((1 << 3) - 1)) 378 #define CLIP(i) ((i) <= 255 ? (i) : 255) 379 380 381 /** 382 * Sets up the palette for the 8-bit color depth configuration so that the 383 * 3:2:3 color scheme can be used. Checks that setting the palette makes sense 384 * (appropriate nodes exist in the OBP tree and the color depth is not greater 348 static void ofw_setup_screen(phandle handle) 349 { 350 /* Check for device type */ 351 char device_type[OFW_TREE_PROPERTY_MAX_VALUELEN]; 352 if (ofw_get_property(handle, "device_type", device_type, OFW_TREE_PROPERTY_MAX_VALUELEN) <= 0) 353 return; 354 355 device_type[OFW_TREE_PROPERTY_MAX_VALUELEN - 1] = '\0'; 356 if (strcmp(device_type, "display") != 0) 357 return; 358 359 /* Check for 8 bit depth */ 360 uint32_t depth; 361 if (ofw_get_property(handle, "depth", &depth, sizeof(uint32_t)) <= 0) 362 depth = 0; 363 364 /* Get device path */ 365 static char path[OFW_TREE_PATH_MAX_LEN + 1]; 366 size_t len = ofw_package_to_path(handle, path, OFW_TREE_PATH_MAX_LEN); 367 if (len == -1) 368 return; 369 370 path[len] = '\0'; 371 372 /* Open the display to initialize it */ 373 ihandle screen = ofw_open(path); 374 if (screen == -1) 375 return; 376 377 if (depth == 8) { 378 /* Setup the palette so that the (inverted) 3:2:3 scheme is usable */ 379 unsigned int i; 380 for (i = 0; i < 256; i++) { 381 ofw_call("call-method", 6, 1, NULL, "color!", screen, 382 255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37)); 383 } 384 } 385 } 386 387 static void ofw_setup_screens_internal(phandle current) 388 { 389 while ((current != 0) && (current != -1)) { 390 ofw_setup_screen(current); 391 392 /* 393 * Recursively process the potential child node. 394 */ 395 phandle child = ofw_get_child_node(current); 396 if ((child != 0) && (child != -1)) 397 ofw_setup_screens_internal(child); 398 399 /* 400 * Iteratively process the next peer node. 401 * Note that recursion is a bad idea here. 402 * Due to the topology of the OpenFirmware device tree, 403 * the nesting of peer nodes could be to wide and the 404 * risk of overflowing the stack is too real. 405 */ 406 phandle peer = ofw_get_peer_node(current); 407 if ((peer != 0) && (peer != -1)) { 408 current = peer; 409 /* 410 * Process the peer in next iteration. 411 */ 412 continue; 413 } 414 415 /* 416 * No more peers on this level. 417 */ 418 break; 419 } 420 } 421 422 /** Setup all screens which can be detected. 423 * 424 * Open all screens which can be detected and set up the palette for the 8-bit 425 * color depth configuration so that the 3:2:3 color scheme can be used. 426 * Check that setting the palette makes sense (the color depth is not greater 385 427 * than 8). 386 428 * 387 * @return true if the palette has been set, false otherwise388 *389 429 */ 390 int ofw_setup_palette(void) 391 { 392 char device_name[BUF_SIZE]; 393 394 /* resolve alias */ 395 if (ofw_get_property(ofw_aliases, "screen", device_name, 396 sizeof(device_name)) <= 0) 397 return false; 398 399 /* for depth greater than 8 it makes no sense to set up the palette */ 400 uint32_t depth; 401 phandle device = ofw_find_device(device_name); 402 if (device == -1) 403 return false; 404 if (ofw_get_property(device, "depth", &depth, sizeof(uint32_t)) <= 0) 405 return false; 406 if (depth != 8) 407 return false; 408 409 /* required in order to be able to make a method call */ 410 ihandle screen = ofw_open(device_name); 411 if (screen == -1) 412 return false; 413 414 /* setup the palette so that the (inverted) 3:2:3 scheme is usable */ 415 unsigned int i; 416 for (i = 0; i < 256; i++) 417 ofw_call("call-method", 6, 1, NULL, "color!", screen, 418 255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37)); 419 return true; 430 void ofw_setup_screens(void) 431 { 432 ofw_setup_screens_internal(ofw_root); 420 433 } 421 434
Note:
See TracChangeset
for help on using the changeset viewer.