#include <sys/kdebug.h>
#include "iso_font.c"
+#if !CONFIG_EMBEDDED
#include "progress_meter_data.c"
+#endif
#include "sys/msgbuf.h"
{
/* secs */
kProgressAcquireDelay = 0,
+#if CONFIG_EMBEDDED
+ kProgressReacquireDelay = 5,
+#else
kProgressReacquireDelay = 5,
+#endif
};
static int8_t vc_rotate_matr[4][2][2] = {
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;
void
vcputc(__unused int l, __unused int u, int c)
{
- if ( gc_initialized && ( gc_enabled || debug_mode ) )
+ if ( gc_initialized && gc_enabled )
{
spl_t s;
x86_filter_TLB_coherency_interrupts(TRUE);
#endif
VCPUTC_LOCK_LOCK();
- if ( gc_enabled || debug_mode )
+ if ( gc_enabled )
{
gc_hide_cursor(gc_x, gc_y);
gc_putchar(c);
#define REN_MAX_DEPTH 32
static unsigned char vc_rendered_char[ISO_CHAR_HEIGHT * ((REN_MAX_DEPTH / 8) * ISO_CHAR_WIDTH)];
+#if !CONFIG_EMBEDDED
static void
internal_set_progressmeter(int new_value);
static void
kProgressMeterEnd = 512,
};
+#endif /* !CONFIG_EMBEDDED */
static boolean_t vc_progress_white =
#ifdef CONFIG_VC_PROGRESS_WHITE
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)
+#if !CONFIG_EMBEDDED
static int vc_progress_withmeter = 3;
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;
static boolean_t vc_progressmeter_hold;
static uint32_t vc_progressmeter_diskspeed = 256;
+#endif /* !CONFIG_EMBEDDED */
+
enum {
kSave = 0x10,
kDataIndexed = 0x20,
unsigned int * backBuffer,
unsigned int flags);
static void vc_progress_task( void * arg0, void * arg );
+#if !CONFIG_EMBEDDED
static void vc_progressmeter_task( void * arg0, void * arg );
+#endif /* !CONFIG_EMBEDDED */
static void vc_blit_rect(int x, int y, int bx,
int width, int height,
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:
/* For ARM, 16-bit is 565 (RGB); it is 1555 (XRGB) on other platforms */
+#ifdef __arm__
+#define CLUT_MASK_R 0xf8
+#define CLUT_MASK_G 0xfc
+#define CLUT_MASK_B 0xf8
+#define CLUT_SHIFT_R << 8
+#define CLUT_SHIFT_G << 3
+#define CLUT_SHIFT_B >> 3
+#define MASK_R 0xf800
+#define MASK_G 0x07e0
+#define MASK_B 0x001f
+#define MASK_R_8 0x7f800
+#define MASK_G_8 0x01fe0
+#define MASK_B_8 0x000ff
+#else
#define CLUT_MASK_R 0xf8
#define CLUT_MASK_G 0xf8
#define CLUT_MASK_B 0xf8
#define MASK_R_8 0x3fc00
#define MASK_G_8 0x01fe0
#define MASK_B_8 0x000ff
+#endif
static void vc_blit_rect_16( int x, int y, int bx,
int width, int height,
{
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);
static void vc_clean_boot_graphics(void)
{
+#if !CONFIG_EMBEDDED
// clean up possible FDE login graphics
vc_progress_set(FALSE, 0);
const unsigned char *
color = (typeof(color))(uintptr_t)(vc_progress_white ? 0x00000000 : 0xBFBFBFBF);
vc_blit_rect(0, 0, 0, vinfo.v_width, vinfo.v_height, 0, 0, color, NULL, 0);
+#endif
}
/*
clock_interval_to_absolutetime_interval(vc_progress->time, 1000 * 1000, &abstime);
vc_progress_interval = (uint32_t)abstime;
+#if !CONFIG_EMBEDDED
thread_call_setup(&vc_progressmeter_call, vc_progressmeter_task, NULL);
clock_interval_to_absolutetime_interval(1000 / 8, 1000 * 1000, &abstime);
vc_progressmeter_interval = (uint32_t)abstime;
+#endif /* !CONFIG_EMBEDDED */
}
unsigned int pdata32;
unsigned int * buf32;
+#if !CONFIG_EMBEDDED
if (kBootArgsFlagBlack & ((boot_args *) PE_state.bootArgs)->flags) return;
return;
}
+#endif /* !CONFIG_EMBEDDED */
if(!vc_progress) return;
if( enable) {
- saveLen = (vc_progress->width * vc_uiscale) * (vc_progress->height * vc_uiscale) * vinfo.v_depth / 8;
+ saveLen = (vc_progress->width * vc_uiscale) * (vc_progress->height * vc_uiscale) * ((vinfo.v_depth + 7) / 8);
saveBuf = kalloc( saveLen );
switch( vinfo.v_depth) {
kfree( saveBuf, saveLen );
}
+#if !CONFIG_EMBEDDED
+
+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)
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 };
vc_progressmeter_diskspeed = speed;
}
+#endif /* !CONFIG_EMBEDDED */
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) {
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);
}
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 )
{
if (vc_progress_enable)
{
+#if !CONFIG_EMBEDDED
if (1 & vc_progress_withmeter) thread_call_enter_delayed(&vc_progressmeter_call, vc_progressmeter_deadline);
else
+#endif /* !CONFIG_EMBEDDED */
thread_call_enter_delayed(&vc_progress_call, vc_progress_deadline);
}
static void
vc_initialize(__unused struct vc_info * vinfo_p)
{
+#ifdef __arm__
+ unsigned long cnt, data16, data32;
+
+ if (vinfo.v_depth == 16) {
+ for (cnt = 0; cnt < 8; cnt++) {
+ data32 = vc_colors[cnt][2];
+ data16 = (data32 & 0x0000F8) << 8;
+ data16 |= (data32 & 0x00FC00) >> 5;
+ data16 |= (data32 & 0xF80000) >> 19;
+ data16 |= data16 << 16;
+ vc_colors[cnt][1] = data16;
+ }
+ }
+#endif
vinfo.v_rows = vinfo.v_height / ISO_CHAR_HEIGHT;
vinfo.v_columns = vinfo.v_width / ISO_CHAR_WIDTH;
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
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 */
}
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)
// 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)
break;
case kPETextMode:
- disable_debug_output = FALSE;
gc_graphics_boot = FALSE;
break;
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;
+
+#if !defined(XNU_TARGET_OS_BRIDGE)
+ vc_progress_set( graphics_now, delay );
+#endif /* !defined(XNU_TARGET_OS_BRIDGE) */
gc_enable( !graphics_now );
gc_acquired = TRUE;
gc_desire_text = FALSE;
case kPETextScreen:
if ( console_is_serial() ) break;
- disable_debug_output = FALSE;
if ( gc_acquired == FALSE )
{
gc_desire_text = TRUE;
if ( gc_graphics_boot == FALSE ) break;
vc_progress_set( FALSE, 0 );
+#if !CONFIG_EMBEDDED
vc_enable_progressmeter( FALSE );
+#endif
gc_enable( TRUE );
break;
vc_progress_set( FALSE, 0 );
vc_acquire_delay = kProgressReacquireDelay;
- vc_enable_progressmeter(FALSE);
vc_progress_white = TRUE;
+#if !CONFIG_EMBEDDED
+ vc_enable_progressmeter(FALSE);
vc_progress_withmeter &= ~1;
+#endif
vc_clut8 = NULL;
break;
+#if !CONFIG_EMBEDDED
case kPERefreshBootGraphics:
{
spl_t s;
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);
internal_enable_progressmeter(kProgressMeterOff);
vc_progress_white = save;
}
- }
-}
-
-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;
- }
+#endif
}
}
{
vm_initialized = TRUE;
+#if !CONFIG_EMBEDDED
+ 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;
+ }
+#endif
simple_lock_init(&vc_progress_lock, 0);
if ( gc_graphics_boot == FALSE )
}
}
+#if !CONFIG_EMBEDDED
// redraw progress meter between pixels x1, x2, position at x3
static void
splx(s);
}
+#endif /* !CONFIG_EMBEDDED */
+
+