Changes in boot/genarch/ofw.c [e0565005:fd375a8d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/genarch/ofw.c
re0565005 rfd375a8d 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)40 34 41 35 uintptr_t ofw_cif; … … 47 41 ihandle ofw_memory_prop; 48 42 phandle ofw_memory; 43 phandle ofw_aliases; 49 44 50 45 void ofw_init(void) … … 74 69 halt(); 75 70 } 76 71 77 72 ofw_memory = ofw_find_device("/memory"); 78 73 if (ofw_memory == -1) { … … 80 75 halt(); 81 76 } 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 } 82 83 } 83 84 84 85 /** Perform a call to OpenFirmware client interface. 85 86 * 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 * 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. 95 95 */ 96 96 unsigned long … … 127 127 } 128 128 129 int ofw_get_property(const phandle device, const char *name, void *buf, 129 int 130 ofw_get_property(const phandle device, const char *name, void *buf, 130 131 const int buflen) 131 132 { … … 160 161 } 161 162 163 162 164 unsigned int ofw_get_size_cells(const phandle device) 163 165 { … … 219 221 } 220 222 221 void *ofw_claim_virt(const void *virt, const unsignedint len)223 void *ofw_claim_virt(const void *virt, const int len) 222 224 { 223 225 ofw_arg_t retaddr; … … 232 234 } 233 235 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 236 void *ofw_claim_phys(const void *phys, const int len) 237 { 238 ofw_arg_t retaddr[2]; 239 int shift; 240 248 241 if (sizeof(unative_t) == 8) { 249 ofw_arg_t retaddr[2]; 250 int shift = 32; 251 242 shift = 32; 252 243 if (ofw_call("call-method", 6, 3, retaddr, "claim", 253 ofw_memory_prop, alignment, len, ((uintptr_t) phys) >> shift,244 ofw_memory_prop, 0, len, ((uintptr_t) phys) >> shift, 254 245 ((uintptr_t) phys) & ((uint32_t) -1)) != 0) { 246 /* 247 * Note that this will help us to discover 248 * conflicts between OpenFirmware allocations 249 * and our use of physical memory. 250 * It is better to detect collisions here 251 * than to cope with weird errors later. 252 * 253 * So this is really not to make the loader 254 * more generic; it is here for debugging 255 * purposes. 256 */ 255 257 puts("Error: memory method claim() failed, halting.\n"); 256 258 halt(); 257 259 } 258 259 return (void *) ((retaddr[0] << shift) | retaddr[1]);260 260 } else { 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) 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) 284 273 { 285 274 uintptr_t phys_hi, phys_lo; … … 325 314 326 315 /* 327 * This is a hot fix of the issue which occurs on machines328 * where there are holes in the physical memory (such as329 * SunBlade 1500). Should we detect a hole in the physical330 * memory, we will ignore any memory detected behind331 * the hole and pretend the hole does not exist.316 * This is a hot fix of the issue which occurs on machines 317 * where there are holes in the physical memory (such as 318 * SunBlade 1500). Should we detect a hole in the physical 319 * memory, we will ignore any memory detected behind 320 * the hole and pretend the hole does not exist. 332 321 */ 333 322 if ((map->count > 0) && (map->zones[map->count - 1].start + … … 346 335 } 347 336 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 */ 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 385 * than 8). 386 * 387 * @return true if the palette has been set, false otherwise 388 * 389 */ 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 */ 360 400 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); 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); 374 411 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 427 * than 8). 428 * 429 */ 430 void ofw_setup_screens(void) 431 { 432 ofw_setup_screens_internal(ofw_root); 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; 433 420 } 434 421
Note:
See TracChangeset
for help on using the changeset viewer.