X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..4d15aeb193b2c68f1d38666c317f8d3734f5f083:/osfmk/console/video_console.c?ds=sidebyside diff --git a/osfmk/console/video_console.c b/osfmk/console/video_console.c index e696d5c30..5295d3c03 100644 --- a/osfmk/console/video_console.c +++ b/osfmk/console/video_console.c @@ -441,6 +441,10 @@ gc_enable( boolean_t enable ) if ( buffer_colorcodes ) kfree( buffer_colorcodes, buffer_size ); if ( buffer_tab_stops ) kfree( buffer_tab_stops, buffer_columns ); + buffer_attributes = NULL; + buffer_characters = NULL; + buffer_colorcodes = NULL; + buffer_tab_stops = NULL; buffer_columns = 0; buffer_rows = 0; buffer_size = 0; @@ -1856,6 +1860,9 @@ static boolean_t vc_needsave; static void * vc_saveunder; static vm_size_t vc_saveunder_len; static int8_t vc_uiscale = 1; +vc_progress_user_options vc_progress_options; +vc_progress_user_options vc_user_options; + decl_simple_lock_data(,vc_progress_lock) static int vc_progress_withmeter = 3; @@ -1863,6 +1870,8 @@ int vc_progressmeter_enable; static int vc_progressmeter_drawn; int vc_progressmeter_value; static uint32_t vc_progressmeter_count; +static uint32_t vc_progress_meter_start; +static uint32_t vc_progress_meter_end; static uint64_t vc_progressmeter_interval; static uint64_t vc_progressmeter_deadline; static thread_call_data_t vc_progressmeter_call; @@ -1870,6 +1879,7 @@ static void * vc_progressmeter_backbuffer; static boolean_t vc_progressmeter_hold; static uint32_t vc_progressmeter_diskspeed = 256; + enum { kSave = 0x10, kDataIndexed = 0x20, @@ -1922,8 +1932,9 @@ static void vc_blit_rect(int x, int y, int bx, void * backBuffer, unsigned int flags) { - if(!vinfo.v_depth) - return; + if (!vinfo.v_depth) return; + if (((unsigned int)(x + width)) > vinfo.v_width) return; + if (((unsigned int)(y + height)) > vinfo.v_height) return; switch( vinfo.v_depth) { case 8: @@ -2165,9 +2176,8 @@ static void vc_blit_rect_30(int x, int y, int bx, { for( col = 0; col < width; col++) { - if (col < sourceRow) - data = *dataPtr++; - + if (sourceRow) data = dataPtr[((sx + (col * a) + (line * b)) >> 16) + + sourceRow * (((sy + (col * c) + (line * d)) >> 16))]; if (backPtr) { if (kSave & flags) { back = *(dst + col); @@ -2535,6 +2545,17 @@ vc_progress_set(boolean_t enable, uint32_t vc_delay) } +static uint32_t vc_progressmeter_range(uint32_t pos) +{ + uint32_t ret; + + if (pos > kProgressMeterEnd) pos = kProgressMeterEnd; + ret = vc_progress_meter_start + + ((pos * (vc_progress_meter_end - vc_progress_meter_start)) / kProgressMeterEnd); + + return (ret); +} + static void vc_progressmeter_task(__unused void *arg0, __unused void *arg) { @@ -2546,7 +2567,7 @@ vc_progressmeter_task(__unused void *arg0, __unused void *arg) if (vc_progressmeter_enable) { uint32_t pos = (vc_progressmeter_count >> 13); - internal_set_progressmeter(pos); + internal_set_progressmeter(vc_progressmeter_range(pos)); if (pos < kProgressMeterEnd) { static uint16_t incr[8] = { 10000, 10000, 8192, 4096, 2048, 384, 384, 64 }; @@ -2572,14 +2593,15 @@ void vc_progress_setdiskspeed(uint32_t speed) static void vc_progress_task(__unused void *arg0, __unused void *arg) { - spl_t s; - int x, y, width, height; + spl_t s; + int x, y, width, height; + uint64_t x_pos, y_pos; const unsigned char * data; s = splhigh(); simple_lock(&vc_progress_lock); - if( vc_progress_enable) { + if( vc_progress_enable) do { vc_progress_count++; if( vc_progress_count >= vc_progress->count) { @@ -2589,32 +2611,59 @@ vc_progress_task(__unused void *arg0, __unused void *arg) width = (vc_progress->width * vc_uiscale); height = (vc_progress->height * vc_uiscale); - x = (vc_progress->dx * vc_uiscale); - y = (vc_progress->dy * vc_uiscale); - data = vc_progress_data[vc_uiscale - 1]; - if (data) - { - data += vc_progress_count * width * height; + data = vc_progress_data[vc_uiscale - 1]; + if (!data) break; + + if (kVCUsePosition & vc_progress_options.options) { + /* Rotation: 0:normal, 1:right 90, 2:left 180, 3:left 90 */ + switch (3 & vinfo.v_rotate) { + case 0: + x_pos = vc_progress_options.x_pos; + y_pos = vc_progress_options.y_pos; + break; + case 2: + x_pos = 0xFFFFFFFF - vc_progress_options.x_pos; + y_pos = 0xFFFFFFFF - vc_progress_options.y_pos; + break; + case 1: + x_pos = 0xFFFFFFFF - vc_progress_options.y_pos; + y_pos = vc_progress_options.x_pos; + break; + case 3: + x_pos = vc_progress_options.y_pos; + y_pos = 0xFFFFFFFF - vc_progress_options.x_pos; + break; + } + x = (uint32_t)((x_pos * (uint64_t) vinfo.v_width) / 0xFFFFFFFFULL); + y = (uint32_t)((y_pos * (uint64_t) vinfo.v_height) / 0xFFFFFFFFULL); + x -= (width / 2); + y -= (height / 2); + } else { + x = (vc_progress->dx * vc_uiscale); + y = (vc_progress->dy * vc_uiscale); if( 1 & vc_progress->flags) { x += ((vinfo.v_width - width) / 2); y += ((vinfo.v_height - height) / 2); } - - assert(((x + width) < (int)vinfo.v_width) && - ((y + height) < (int)vinfo.v_height)); - - vc_blit_rect( x, y, 0, - width, height, width, width, - data, vc_saveunder, - kDataAlpha - | (vc_progress_angle & kDataRotate) - | (vc_needsave ? kSave : 0) ); - vc_needsave = FALSE; - - clock_deadline_for_periodic_event(vc_progress_interval, mach_absolute_time(), &vc_progress_deadline); - thread_call_enter_delayed(&vc_progress_call, vc_progress_deadline); } + + if ((x + width) > (int)vinfo.v_width) break; + if ((y + height) > (int)vinfo.v_height) break; + + data += vc_progress_count * width * height; + + vc_blit_rect( x, y, 0, + width, height, width, width, + data, vc_saveunder, + kDataAlpha + | (vc_progress_angle & kDataRotate) + | (vc_needsave ? kSave : 0) ); + vc_needsave = FALSE; + + clock_deadline_for_periodic_event(vc_progress_interval, mach_absolute_time(), &vc_progress_deadline); + thread_call_enter_delayed(&vc_progress_call, vc_progress_deadline); } + while (FALSE); simple_unlock(&vc_progress_lock); splx(s); } @@ -2633,10 +2682,10 @@ static boolean_t gc_graphics_boot = FALSE; static boolean_t gc_desire_text = FALSE; static boolean_t gc_paused_progress; -static uint64_t lastVideoPhys = 0; -static vm_offset_t lastVideoVirt = 0; -static vm_size_t lastVideoSize = 0; -static boolean_t lastVideoMapped = FALSE; +static vm_offset_t lastVideoVirt = 0; +static vm_size_t lastVideoMapSize = 0; +static boolean_t lastVideoMapKmap = FALSE; + static void gc_pause( boolean_t pause, boolean_t graphics_now ) { @@ -2685,28 +2734,29 @@ vc_initialize(__unused struct vc_info * vinfo_p) void initialize_screen(PE_Video * boot_vinfo, unsigned int op) { - unsigned int fbsize = 0; + unsigned int newMapSize = 0; vm_offset_t newVideoVirt = 0; boolean_t graphics_now; - ppnum_t fbppage; + uint32_t delay; if ( boot_vinfo ) { struct vc_info new_vinfo = vinfo; + boolean_t makeMapping = FALSE; + /* - * First, check if we are changing the size and/or location of the framebuffer + * Copy parameters */ - new_vinfo.v_name[0] = 0; - new_vinfo.v_physaddr = boot_vinfo->v_baseAddr & ~3; /* Get the physical address */ -#ifndef __LP64__ - new_vinfo.v_physaddr |= (((uint64_t) boot_vinfo->v_baseAddrHigh) << 32); -#endif if (kPEBaseAddressChange != op) { new_vinfo.v_width = (unsigned int)boot_vinfo->v_width; new_vinfo.v_height = (unsigned int)boot_vinfo->v_height; new_vinfo.v_depth = (unsigned int)boot_vinfo->v_depth; new_vinfo.v_rowbytes = (unsigned int)boot_vinfo->v_rowBytes; + if (kernel_map == VM_MAP_NULL) { + // only booter supplies HW rotation + new_vinfo.v_rotate = (unsigned int)boot_vinfo->v_rotate; + } #if defined(__i386__) || defined(__x86_64__) new_vinfo.v_type = (unsigned int)boot_vinfo->v_display; #else @@ -2719,14 +2769,28 @@ initialize_screen(PE_Video * boot_vinfo, unsigned int op) new_vinfo.v_scale = kPEScaleFactor2x; else /* Scale factor not set, default to 1x */ new_vinfo.v_scale = kPEScaleFactor1x; + } + new_vinfo.v_name[0] = 0; + new_vinfo.v_physaddr = 0; + /* + * Check if we are have to map the framebuffer + * If VM is up, we are given a virtual address, unless b0 is set to indicate physical. + */ + newVideoVirt = boot_vinfo->v_baseAddr; + makeMapping = (kernel_map == VM_MAP_NULL) || (0 != (1 & newVideoVirt)); + if (makeMapping) + { + newVideoVirt = 0; + new_vinfo.v_physaddr = boot_vinfo->v_baseAddr & ~3UL; /* Get the physical address */ +#ifndef __LP64__ + new_vinfo.v_physaddr |= (((uint64_t) boot_vinfo->v_baseAddrHigh) << 32); +#endif + kprintf("initialize_screen: b=%08llX, w=%08X, h=%08X, r=%08X, d=%08X\n", /* (BRINGUP) */ + new_vinfo.v_physaddr, new_vinfo.v_width, new_vinfo.v_height, new_vinfo.v_rowbytes, new_vinfo.v_type); /* (BRINGUP) */ } - if (!lastVideoMapped) - kprintf("initialize_screen: b=%08llX, w=%08X, h=%08X, r=%08X, d=%08X\n", /* (BRINGUP) */ - new_vinfo.v_physaddr, new_vinfo.v_width, new_vinfo.v_height, new_vinfo.v_rowbytes, new_vinfo.v_type); /* (BRINGUP) */ - - if (!new_vinfo.v_physaddr) /* Check to see if we have a framebuffer */ + if (!newVideoVirt && !new_vinfo.v_physaddr) /* Check to see if we have a framebuffer */ { kprintf("initialize_screen: No video - forcing serial mode\n"); /* (BRINGUP) */ new_vinfo.v_depth = 0; /* vc routines are nop */ @@ -2737,36 +2801,17 @@ initialize_screen(PE_Video * boot_vinfo, unsigned int op) } else { - /* - * If VM is up, we are given a virtual address, unless b0 is set to indicate physical. - */ - if ((kernel_map != VM_MAP_NULL) && (0 == (1 & boot_vinfo->v_baseAddr))) - { - fbppage = pmap_find_phys(kernel_pmap, (addr64_t)boot_vinfo->v_baseAddr); /* Get the physical address of frame buffer */ - if(!fbppage) /* Did we find it? */ - { - panic("initialize_screen: Strange framebuffer - addr = %08X\n", (uint32_t)boot_vinfo->v_baseAddr); - } - new_vinfo.v_physaddr = (((uint64_t)fbppage) << PAGE_SHIFT) | (boot_vinfo->v_baseAddr & PAGE_MASK); /* Get the physical address */ - } - - if (boot_vinfo->v_length != 0) - fbsize = (unsigned int) round_page(boot_vinfo->v_length); - else - fbsize = (unsigned int) round_page(new_vinfo.v_height * new_vinfo.v_rowbytes); /* Remember size */ - - - if ((lastVideoPhys != new_vinfo.v_physaddr) || (fbsize > lastVideoSize)) /* Did framebuffer change location or get bigger? */ + if (makeMapping) { unsigned int flags = VM_WIMG_IO; - newVideoVirt = io_map_spec((vm_map_offset_t)new_vinfo.v_physaddr, fbsize, flags); /* Allocate address space for framebuffer */ - } - } - - if (newVideoVirt != 0) + if (boot_vinfo->v_length != 0) + newMapSize = (unsigned int) round_page(boot_vinfo->v_length); + else + newMapSize = (unsigned int) round_page(new_vinfo.v_height * new_vinfo.v_rowbytes); /* Remember size */ + newVideoVirt = io_map_spec((vm_map_offset_t)new_vinfo.v_physaddr, newMapSize, flags); /* Allocate address space for framebuffer */ + } new_vinfo.v_baseaddr = newVideoVirt + boot_vinfo->v_offset; /* Set the new framebuffer address */ - else - new_vinfo.v_baseaddr = lastVideoVirt + boot_vinfo->v_offset; /* Set the new framebuffer address */ + } #if defined(__x86_64__) // Adjust the video buffer pointer to point to where it is in high virtual (above the hole) @@ -2788,24 +2833,23 @@ initialize_screen(PE_Video * boot_vinfo, unsigned int op) // If we changed the virtual address, remove the old mapping if (newVideoVirt != 0) { - if (lastVideoVirt) /* Was the framebuffer mapped before? */ + if (lastVideoVirt && lastVideoMapSize) /* Was the framebuffer mapped before? */ { - /* XXX why did this ever succeed? */ - /* TODO: Consider this. */ - if (!TEST_PAGE_SIZE_4K && lastVideoMapped) /* Was this not a special pre-VM mapping? */ + /* XXX why only !4K? */ + if (!TEST_PAGE_SIZE_4K && lastVideoMapSize) { pmap_remove(kernel_pmap, trunc_page_64(lastVideoVirt), - round_page_64(lastVideoVirt + lastVideoSize)); /* Toss mappings */ + round_page_64(lastVideoVirt + lastVideoMapSize)); /* Toss mappings */ } - if(lastVideoMapped) /* Was this not a special pre-VM mapping? */ + /* Was this not a special pre-VM mapping? */ + if (lastVideoMapKmap) { - kmem_free(kernel_map, lastVideoVirt, lastVideoSize); /* Toss kernel addresses */ + kmem_free(kernel_map, lastVideoVirt, lastVideoMapSize); /* Toss kernel addresses */ } } - lastVideoPhys = new_vinfo.v_physaddr; /* Remember the framebuffer address */ - lastVideoSize = fbsize; /* Remember the size */ - lastVideoVirt = newVideoVirt; /* Remember the virtual framebuffer address */ - lastVideoMapped = (NULL != kernel_map); + lastVideoMapKmap = (NULL != kernel_map); /* Remember how mapped */ + lastVideoMapSize = newMapSize; /* Remember the size */ + lastVideoVirt = newVideoVirt; /* Remember the virtual framebuffer address */ } if (kPEBaseAddressChange != op) @@ -2840,7 +2884,18 @@ initialize_screen(PE_Video * boot_vinfo, unsigned int op) case kPEAcquireScreen: if ( gc_acquired ) break; - vc_progress_set( graphics_now, vc_acquire_delay ); + + vc_progress_options = vc_user_options; + bzero(&vc_user_options, sizeof(vc_user_options)); + + if (kVCAcquireImmediate & vc_progress_options.options) delay = 0; + else if (kVCDarkReboot & vc_progress_options.options) delay = 120; + else delay = vc_acquire_delay; + + if (kVCDarkBackground & vc_progress_options.options) vc_progress_white = TRUE; + else if (kVCLightBackground & vc_progress_options.options) vc_progress_white = FALSE; + + vc_progress_set( graphics_now, delay ); gc_enable( !graphics_now ); gc_acquired = TRUE; gc_desire_text = FALSE; @@ -2884,8 +2939,8 @@ initialize_screen(PE_Video * boot_vinfo, unsigned int op) vc_progress_set( FALSE, 0 ); vc_acquire_delay = kProgressReacquireDelay; - vc_enable_progressmeter(FALSE); vc_progress_white = TRUE; + vc_enable_progressmeter(FALSE); vc_progress_withmeter &= ~1; vc_clut8 = NULL; break; @@ -2907,7 +2962,7 @@ initialize_screen(PE_Video * boot_vinfo, unsigned int op) simple_lock(&vc_progress_lock); vc_progressmeter_drawn = 0; - internal_set_progressmeter(vc_progressmeter_count >> 13); + internal_set_progressmeter(vc_progressmeter_range(vc_progressmeter_count >> 13)); simple_unlock(&vc_progress_lock); splx(s); @@ -2918,39 +2973,6 @@ initialize_screen(PE_Video * boot_vinfo, unsigned int op) } } -void -dim_screen(void) -{ - unsigned int *p, *endp, *row; - int col, rowline, rowlongs; - register unsigned int mask; - - if(!vinfo.v_depth) - return; - - if ( vinfo.v_depth == 32 ) - mask = 0x007F7F7F; - else if ( vinfo.v_depth == 30 ) - mask = (0x1ff<<20) | (0x1ff<<10) | 0x1ff; - else if ( vinfo.v_depth == 16 ) - mask = 0x3DEF3DEF; - else - return; - - rowline = (int)(vinfo.v_rowscanbytes / 4); - rowlongs = (int)(vinfo.v_rowbytes / 4); - - p = (unsigned int*) vinfo.v_baseaddr; - endp = p + (rowlongs * vinfo.v_height); - - for (row = p ; row < endp ; row += rowlongs) { - for (p = &row[0], col = 0; col < rowline; col++) { - *p = (*p >> 1) & mask; - ++p; - } - } -} - void vcattach(void); /* XXX gcc 4 warning cleanup */ void @@ -2958,9 +2980,22 @@ vcattach(void) { vm_initialized = TRUE; + const boot_args * bootargs = (typeof(bootargs)) PE_state.bootArgs; + vc_progress_white = (0 != ((kBootArgsFlagBlackBg | kBootArgsFlagLoginUI) - & ((boot_args *) PE_state.bootArgs)->flags)); + & bootargs->flags)); PE_parse_boot_argn("meter", &vc_progress_withmeter, sizeof(vc_progress_withmeter)); + + if (kBootArgsFlagInstallUI & bootargs->flags) + { + vc_progress_meter_start = (bootargs->bootProgressMeterStart * kProgressMeterMax) / 65535; + vc_progress_meter_end = (bootargs->bootProgressMeterEnd * kProgressMeterMax) / 65535; + } + else + { + vc_progress_meter_start = 0; + vc_progress_meter_end = kProgressMeterMax; + } simple_lock_init(&vc_progress_lock, 0); if ( gc_graphics_boot == FALSE ) @@ -3190,3 +3225,5 @@ vc_set_progressmeter(int new_value) } + +