/*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
*
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the
- * License may not be used to create, or enable the creation or
- * redistribution of, unlawful or unlicensed copies of an Apple operating
- * system, or to circumvent, violate, or enable the circumvention or
- * violation of, any terms of an Apple operating system software license
- * agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
* limitations under the License.
- *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_FREE_COPYRIGHT@
*
*/
-#include <vc.h>
-
#include <console/video_console.h>
+#include <console/serial_protos.h>
#include <kern/kern_types.h>
#include <kern/kalloc.h>
#include <kern/debug.h>
-#include <kern/lock.h>
#include <kern/spl.h>
#include <kern/thread_call.h>
#include <vm/pmap.h>
#include <vm/vm_kern.h>
+#include <machine/io_map_entries.h>
+#include <machine/machine_cpu.h>
#include <pexpert/pexpert.h>
+#include <sys/kdebug.h>
#include "iso_font.c"
+#include "progress_meter_data.c"
+
+#include "sys/msgbuf.h"
/*
* Generic Console (Front-End)
*/
struct vc_info vinfo;
-/* if panicDialogDesired is true then we use the panic dialog when its */
-/* allowed otherwise we won't use the panic dialog even if it is allowed */
-boolean_t panicDialogDesired;
-
+void noroot_icon_test(void);
+
+
extern int disableConsoleOutput;
static boolean_t gc_enabled = FALSE;
static boolean_t gc_initialized = FALSE;
static struct {
void (*initialize)(struct vc_info * info);
void (*enable)(boolean_t enable);
- void (*paint_char)(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
- void (*clear_screen)(int xx, int yy, int top, int bottom, int which);
- void (*scroll_down)(int num, int top, int bottom);
- void (*scroll_up)(int num, int top, int bottom);
- void (*hide_cursor)(int xx, int yy);
- void (*show_cursor)(int xx, int yy);
+ void (*paint_char)(unsigned int xx, unsigned int yy, unsigned char ch,
+ int attrs, unsigned char ch_previous,
+ int attrs_previous);
+ void (*clear_screen)(unsigned int xx, unsigned int yy, unsigned int top,
+ unsigned int bottom, int which);
+ void (*scroll_down)(int num, unsigned int top, unsigned int bottom);
+ void (*scroll_up)(int num, unsigned int top, unsigned int bottom);
+ void (*hide_cursor)(unsigned int xx, unsigned int yy);
+ void (*show_cursor)(unsigned int xx, unsigned int yy);
void (*update_color)(int color, boolean_t fore);
} gc_ops;
-static unsigned char * gc_buffer_attributes = NULL;
-static unsigned char * gc_buffer_characters = NULL;
-static unsigned char * gc_buffer_colorcodes = NULL;
-static unsigned long gc_buffer_columns = 0;
-static unsigned long gc_buffer_rows = 0;
-static unsigned long gc_buffer_size = 0;
-decl_simple_lock_data(,gc_buffer_lock)
+static unsigned char *gc_buffer_attributes;
+static unsigned char *gc_buffer_characters;
+static unsigned char *gc_buffer_colorcodes;
+static unsigned char *gc_buffer_tab_stops;
+static uint32_t gc_buffer_columns;
+static uint32_t gc_buffer_rows;
+static uint32_t gc_buffer_size;
+
+#if defined(__i386__) || defined(__x86_64__)
+decl_simple_lock_data(static, vcputc_lock);
+
+#define VCPUTC_LOCK_INIT() \
+MACRO_BEGIN \
+ simple_lock_init(&vcputc_lock, 0); \
+MACRO_END
+
+#define VCPUTC_LOCK_LOCK() \
+MACRO_BEGIN \
+ boolean_t istate = ml_get_interrupts_enabled(); \
+ while (!simple_lock_try(&vcputc_lock)) \
+ { \
+ if (!istate) \
+ handle_pending_TLB_flushes(); \
+ cpu_pause(); \
+ } \
+MACRO_END
+
+#define VCPUTC_LOCK_UNLOCK() \
+MACRO_BEGIN \
+ simple_unlock(&vcputc_lock); \
+MACRO_END
+#else
+static hw_lock_data_t vcputc_lock;
+
+#define VCPUTC_LOCK_INIT() \
+MACRO_BEGIN \
+ hw_lock_init(&vcputc_lock); \
+MACRO_END
+
+#define VCPUTC_LOCK_LOCK() \
+MACRO_BEGIN \
+ if (!hw_lock_to(&vcputc_lock, ~0U))\
+ { \
+ panic("VCPUTC_LOCK_LOCK"); \
+ } \
+MACRO_END
+
+#define VCPUTC_LOCK_UNLOCK() \
+MACRO_BEGIN \
+ hw_lock_unlock(&vcputc_lock); \
+MACRO_END
+#endif
/*
# Attribute codes:
#define COLOR_CODE_GET(code, fore) (((code) & ((fore) ? 0xF0 : 0x0F)) >> ((fore) ? 4 : 0))
#define COLOR_CODE_SET(code, color, fore) (((code) & ((fore) ? 0x0F : 0xF0)) | ((color) << ((fore) ? 4 : 0)))
-static unsigned char gc_color_code = 0;
+static unsigned char gc_color_code;
/* VT100 state: */
#define MAXPARS 16
-static int gc_x = 0, gc_y = 0, gc_savex, gc_savey;
-static int gc_par[MAXPARS], gc_numpars, gc_hanging_cursor, gc_attr, gc_saveattr;
-
-/* VT100 tab stops & scroll region */
-static char gc_tab_stops[255];
-static int gc_scrreg_top, gc_scrreg_bottom;
+static unsigned int gc_x, gc_y, gc_savex, gc_savey;
+static unsigned int gc_par[MAXPARS], gc_numpars, gc_hanging_cursor, gc_attr, gc_saveattr;
-enum { kProgressAcquireDelay = 5 /* secs */ };
+/* VT100 scroll region */
+static unsigned int gc_scrreg_top, gc_scrreg_bottom;
enum vt100state_e {
ESnormal, /* Nothing yet */
ESignore /* Ignore this sequence */
} gc_vt100state = ESnormal;
+
+enum
+{
+ /* secs */
+ kProgressAcquireDelay = 0,
+ kProgressReacquireDelay = 5,
+};
+
+static int8_t vc_rotate_matr[4][2][2] = {
+ { { 1, 0 },
+ { 0, 1 } },
+ { { 0, 1 },
+ { -1, 0 } },
+ { { -1, 0 },
+ { 0, -1 } },
+ { { 0, -1 },
+ { 1, 0 } }
+};
+
static int gc_wrap_mode = 1, gc_relative_origin = 0;
static int gc_charset_select = 0, gc_save_charset_s = 0;
static int gc_charset[2] = { 0, 0 };
static int gc_charset_save[2] = { 0, 0 };
-static void gc_clear_line(int xx, int yy, int which);
-static void gc_clear_screen(int xx, int yy, int top, int bottom, int which);
+static void gc_clear_line(unsigned int xx, unsigned int yy, int which);
+static void gc_clear_screen(unsigned int xx, unsigned int yy, int top,
+ unsigned int bottom, int which);
static void gc_enable(boolean_t enable);
-static void gc_hide_cursor(int xx, int yy);
+static void gc_hide_cursor(unsigned int xx, unsigned int yy);
static void gc_initialize(struct vc_info * info);
-static void gc_paint_char(int xx, int yy, unsigned char ch, int attrs);
+static boolean_t gc_is_tab_stop(unsigned int column);
+static void gc_paint_char(unsigned int xx, unsigned int yy, unsigned char ch,
+ int attrs);
static void gc_putchar(char ch);
static void gc_putc_askcmd(unsigned char ch);
static void gc_putc_charsetcmd(int charset, unsigned char ch);
static void gc_putc_gotpars(unsigned char ch);
static void gc_putc_normal(unsigned char ch);
static void gc_putc_square(unsigned char ch);
-static void gc_refresh_screen(void);
static void gc_reset_screen(void);
static void gc_reset_tabs(void);
static void gc_reset_vt100(void);
-static void gc_scroll_down(int num, int top, int bottom);
-static void gc_scroll_up(int num, int top, int bottom);
-static void gc_show_cursor(int xx, int yy);
+static void gc_scroll_down(int num, unsigned int top, unsigned int bottom);
+static void gc_scroll_up(int num, unsigned int top, unsigned int bottom);
+static void gc_set_tab_stop(unsigned int column, boolean_t enabled);
+static void gc_show_cursor(unsigned int xx, unsigned int yy);
static void gc_update_color(int color, boolean_t fore);
-extern int vcputc(int l, int u, int c);
static void
-gc_clear_line(int xx, int yy, int which)
+gc_clear_line(unsigned int xx, unsigned int yy, int which)
{
- int start, end, i;
+ unsigned int start, end, i;
/*
* This routine runs extremely slowly. I don't think it's
start = 0;
end = vinfo.v_columns-1;
break;
+ default:
+ return;
}
for (i = start; i <= end; i++) {
gc_paint_char(i, yy, ' ', ATTR_NONE);
}
-
}
static void
-gc_clear_screen(int xx, int yy, int top, int bottom, int which)
+gc_clear_screen(unsigned int xx, unsigned int yy, int top, unsigned int bottom,
+ int which)
{
- spl_t s;
-
- s = splhigh();
- simple_lock(&gc_buffer_lock);
+ if (!gc_buffer_size) return;
if ( xx < gc_buffer_columns && yy < gc_buffer_rows && bottom <= gc_buffer_rows )
{
- unsigned long start, end;
+ uint32_t start, end;
switch (which) {
case 0: /* To end of screen */
start = (top * gc_buffer_columns);
end = (bottom * gc_buffer_columns) - 1;
break;
+ default:
+ start = 0;
+ end = 0;
+ break;
}
- memset(gc_buffer_attributes + start, 0x00, end - start + 1);
- memset(gc_buffer_characters + start, 0x00, end - start + 1);
+ memset(gc_buffer_attributes + start, ATTR_NONE, end - start + 1);
+ memset(gc_buffer_characters + start, ' ', end - start + 1);
memset(gc_buffer_colorcodes + start, gc_color_code, end - start + 1);
}
- simple_unlock(&gc_buffer_lock);
- splx(s);
-
gc_ops.clear_screen(xx, yy, top, bottom, which);
}
static void
gc_enable( boolean_t enable )
{
- unsigned char * buffer_attributes;
- unsigned char * buffer_characters;
- unsigned char * buffer_colorcodes;
- unsigned long buffer_columns;
- unsigned long buffer_rows;
- unsigned long buffer_size;
-
+ unsigned char *buffer_attributes = NULL;
+ unsigned char *buffer_characters = NULL;
+ unsigned char *buffer_colorcodes = NULL;
+ unsigned char *buffer_tab_stops = NULL;
+ uint32_t buffer_columns = 0;
+ uint32_t buffer_rows = 0;
+ uint32_t buffer_size = 0;
spl_t s;
if ( enable == FALSE )
{
- disableConsoleOutput = TRUE;
+ // only disable console output if it goes to the graphics console
+ if ( console_is_serial() == FALSE )
+ disableConsoleOutput = TRUE;
gc_enabled = FALSE;
gc_ops.enable(FALSE);
}
s = splhigh( );
- simple_lock( &gc_buffer_lock );
+ VCPUTC_LOCK_LOCK( );
if ( gc_buffer_size )
{
buffer_attributes = gc_buffer_attributes;
buffer_characters = gc_buffer_characters;
buffer_colorcodes = gc_buffer_colorcodes;
+ buffer_tab_stops = gc_buffer_tab_stops;
+ buffer_columns = gc_buffer_columns;
+ buffer_rows = gc_buffer_rows;
buffer_size = gc_buffer_size;
gc_buffer_attributes = NULL;
gc_buffer_characters = NULL;
gc_buffer_colorcodes = NULL;
+ gc_buffer_tab_stops = NULL;
gc_buffer_columns = 0;
gc_buffer_rows = 0;
gc_buffer_size = 0;
- simple_unlock( &gc_buffer_lock );
+ VCPUTC_LOCK_UNLOCK( );
splx( s );
kfree( buffer_attributes, buffer_size );
kfree( buffer_characters, buffer_size );
kfree( buffer_colorcodes, buffer_size );
+ kfree( buffer_tab_stops, buffer_columns );
}
else
{
- simple_unlock( &gc_buffer_lock );
+ VCPUTC_LOCK_UNLOCK( );
splx( s );
}
buffer_attributes = (unsigned char *) kalloc( buffer_size );
buffer_characters = (unsigned char *) kalloc( buffer_size );
buffer_colorcodes = (unsigned char *) kalloc( buffer_size );
+ buffer_tab_stops = (unsigned char *) kalloc( buffer_columns );
if ( buffer_attributes == NULL ||
buffer_characters == NULL ||
- buffer_colorcodes == NULL )
+ buffer_colorcodes == NULL ||
+ buffer_tab_stops == NULL )
{
if ( buffer_attributes ) kfree( buffer_attributes, buffer_size );
if ( buffer_characters ) kfree( buffer_characters, buffer_size );
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;
}
else
{
- memset( buffer_attributes, 0x00, buffer_size );
- memset( buffer_characters, 0x00, buffer_size );
- memset( buffer_colorcodes, 0x0F, buffer_size );
+ memset( buffer_attributes, ATTR_NONE, buffer_size );
+ memset( buffer_characters, ' ', buffer_size );
+ memset( buffer_colorcodes, COLOR_CODE_SET( 0, COLOR_FOREGROUND, TRUE ), buffer_size );
+ memset( buffer_tab_stops, 0, buffer_columns );
}
}
}
s = splhigh( );
- simple_lock( &gc_buffer_lock );
+ VCPUTC_LOCK_LOCK( );
gc_buffer_attributes = buffer_attributes;
gc_buffer_characters = buffer_characters;
gc_buffer_colorcodes = buffer_colorcodes;
+ gc_buffer_tab_stops = buffer_tab_stops;
gc_buffer_columns = buffer_columns;
gc_buffer_rows = buffer_rows;
gc_buffer_size = buffer_size;
- simple_unlock( &gc_buffer_lock );
+ gc_reset_screen();
+
+ VCPUTC_LOCK_UNLOCK( );
splx( s );
- gc_reset_screen();
+ gc_ops.clear_screen(gc_x, gc_y, 0, vinfo.v_rows, 2);
+ gc_ops.show_cursor(gc_x, gc_y);
gc_ops.enable(TRUE);
gc_enabled = TRUE;
}
static void
-gc_hide_cursor(int xx, int yy)
+gc_hide_cursor(unsigned int xx, unsigned int yy)
{
- spl_t s;
-
- s = splhigh();
- simple_lock(&gc_buffer_lock);
-
if ( xx < gc_buffer_columns && yy < gc_buffer_rows )
{
- unsigned long index = (yy * gc_buffer_columns) + xx;
+ uint32_t index = (yy * gc_buffer_columns) + xx;
unsigned char attribute = gc_buffer_attributes[index];
unsigned char character = gc_buffer_characters[index];
unsigned char colorcode = gc_buffer_colorcodes[index];
unsigned char colorcodesave = gc_color_code;
- simple_unlock(&gc_buffer_lock);
- splx(s);
-
gc_update_color(COLOR_CODE_GET(colorcode, TRUE ), TRUE );
gc_update_color(COLOR_CODE_GET(colorcode, FALSE), FALSE);
}
else
{
- simple_unlock(&gc_buffer_lock);
- splx(s);
-
gc_ops.hide_cursor(xx, yy);
}
}
if ( gc_initialized == FALSE )
{
/* Init our lock */
- simple_lock_init(&gc_buffer_lock, 0);
+ VCPUTC_LOCK_INIT();
gc_initialized = TRUE;
}
}
static void
-gc_paint_char(int xx, int yy, unsigned char ch, int attrs)
+gc_paint_char(unsigned int xx, unsigned int yy, unsigned char ch, int attrs)
{
- spl_t s;
-
- s = splhigh();
- simple_lock(&gc_buffer_lock);
-
if ( xx < gc_buffer_columns && yy < gc_buffer_rows )
{
- unsigned long index = (yy * gc_buffer_columns) + xx;
+ uint32_t index = (yy * gc_buffer_columns) + xx;
gc_buffer_attributes[index] = attrs;
gc_buffer_characters[index] = ch;
gc_buffer_colorcodes[index] = gc_color_code;
}
- simple_unlock(&gc_buffer_lock);
- splx(s);
-
gc_ops.paint_char(xx, yy, ch, attrs, 0, 0);
}
}
if (gc_x >= vinfo.v_columns) {
- gc_x = vinfo.v_columns - 1;
- }
- if (gc_x < 0) {
- gc_x = 0;
+ if (0 == vinfo.v_columns)
+ gc_x = 0;
+ else
+ gc_x = vinfo.v_columns - 1;
}
if (gc_y >= vinfo.v_rows) {
- gc_y = vinfo.v_rows - 1;
- }
- if (gc_y < 0) {
- gc_y = 0;
+ if (0 == vinfo.v_rows)
+ gc_y = 0;
+ else
+ gc_y = vinfo.v_rows - 1;
}
-
}
static void
break;
case '8' : /* fill 'E's */
{
- int xx, yy;
+ unsigned int xx, yy;
for (yy = 0; yy < vinfo.v_rows; yy++)
for (xx = 0; xx < vinfo.v_columns; xx++)
gc_paint_char(xx, yy, 'E', ATTR_NONE);
if (ch == 'E') gc_x = 0;
break;
case 'H': /* Set tab stop */
- gc_tab_stops[gc_x] = 1;
+ gc_set_tab_stop(gc_x, TRUE);
break;
case 'M': /* Cursor up */
if (gc_y <= gc_scrreg_top) {
static void
gc_putc_gotpars(unsigned char ch)
{
- int i;
+ unsigned int i;
if (ch < ' ') {
/* special case for vttest for handling cursor
gc_x = vinfo.v_columns-1;
break;
case 'D': /* Left */
- gc_x -= gc_par[0] ? gc_par[0] : 1;
- if (gc_x < 0)
+ if (gc_par[0] > gc_x)
gc_x = 0;
+ else if (gc_par[0])
+ gc_x -= gc_par[0];
+ else if (gc_x)
+ --gc_x;
break;
case 'H': /* Set cursor position */
case 'f':
break;
case 'X': /* clear p1 characters */
if (gc_numpars) {
- int i;
for (i = gc_x; i < gc_x + gc_par[0]; i++)
gc_paint_char(i, gc_y, ' ', ATTR_NONE);
}
break;
case 3: /* Clear every tabs */
{
- int i;
-
for (i = 0; i <= vinfo.v_columns; i++)
- gc_tab_stops[i] = 0;
+ gc_set_tab_stop(i, FALSE);
}
break;
case 0:
- gc_tab_stops[gc_x] = 0;
+ gc_set_tab_stop(gc_x, FALSE);
break;
}
break;
/* ensure top < bottom, and both within limits */
if ((gc_numpars > 0) && (gc_par[0] < vinfo.v_rows)) {
gc_scrreg_top = gc_par[0] ? gc_par[0] - 1 : 0;
- if (gc_scrreg_top < 0)
- gc_scrreg_top = 0;
} else {
gc_scrreg_top = 0;
}
}
break;
case '\t': /* Tab */
- while (gc_x < vinfo.v_columns && !gc_tab_stops[++gc_x]);
+ if (gc_buffer_tab_stops) while (gc_x < vinfo.v_columns && !gc_is_tab_stop(++gc_x));
+
if (gc_x >= vinfo.v_columns)
gc_x = vinfo.v_columns-1;
break;
}
-static void
-gc_refresh_screen(void)
-{
- spl_t s;
-
- s = splhigh();
- simple_lock(&gc_buffer_lock);
-
- if ( gc_buffer_size )
- {
- unsigned char colorcodesave = gc_color_code;
- unsigned long column, row;
- unsigned long index;
-
- for ( index = 0, row = 0 ; row < gc_buffer_rows ; row++ )
- {
- for ( column = 0 ; column < gc_buffer_columns ; index++, column++ )
- {
- if ( gc_buffer_colorcodes[index] != gc_color_code )
- {
- gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes[index], TRUE ), TRUE );
- gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes[index], FALSE), FALSE);
- }
-
- gc_ops.paint_char(column, row, gc_buffer_characters[index], gc_buffer_attributes[index], 0, 0);
- }
- }
-
- if ( colorcodesave != gc_color_code )
- {
- gc_update_color(COLOR_CODE_GET(colorcodesave, TRUE ), TRUE );
- gc_update_color(COLOR_CODE_GET(colorcodesave, FALSE), FALSE);
- }
- }
-
- simple_unlock(&gc_buffer_lock);
- splx(s);
-}
-
static void
gc_reset_screen(void)
{
- gc_hide_cursor(gc_x, gc_y);
gc_reset_vt100();
gc_x = gc_y = 0;
- gc_clear_screen(gc_x, gc_y, 0, vinfo.v_rows, 2);
- gc_show_cursor(gc_x, gc_y);
}
static void
gc_reset_tabs(void)
{
- int i;
+ unsigned int i;
+
+ if (!gc_buffer_tab_stops) return;
- for (i = 0; i<= vinfo.v_columns; i++) {
- gc_tab_stops[i] = ((i % 8) == 0);
+ for (i = 0; i < vinfo.v_columns; i++) {
+ gc_buffer_tab_stops[i] = ((i % 8) == 0);
}
}
+static void
+gc_set_tab_stop(unsigned int column, boolean_t enabled)
+{
+ if (gc_buffer_tab_stops && (column < vinfo.v_columns)) {
+ gc_buffer_tab_stops[column] = enabled;
+ }
+}
+
+static boolean_t gc_is_tab_stop(unsigned int column)
+{
+ if (gc_buffer_tab_stops == NULL)
+ return ((column % 8) == 0);
+ if (column < vinfo.v_columns)
+ return gc_buffer_tab_stops[column];
+ else
+ return FALSE;
+}
+
static void
gc_reset_vt100(void)
{
}
static void
-gc_scroll_down(int num, int top, int bottom)
+gc_scroll_down(int num, unsigned int top, unsigned int bottom)
{
- spl_t s;
-
- s = splhigh();
- simple_lock(&gc_buffer_lock);
+ if (!gc_buffer_size) return;
if ( bottom <= gc_buffer_rows )
{
unsigned char colorcodesave = gc_color_code;
- unsigned long column, row;
- unsigned long index, jump;
+ uint32_t column, row;
+ uint32_t index, jump;
jump = num * gc_buffer_columns;
gc_update_color(COLOR_CODE_GET(colorcodesave, FALSE), FALSE);
}
- simple_unlock(&gc_buffer_lock);
- splx(s);
+ /* Now set the freed up lines to the background colour */
+
+ for ( row = top ; row < top + num ; row++ )
+ {
+ index = row * gc_buffer_columns;
+
+ for ( column = 0 ; column < gc_buffer_columns ; index++, column++ )
+ {
+ if ( gc_buffer_attributes[index] != ATTR_NONE ||
+ gc_buffer_characters[index] != ' ' ||
+ gc_buffer_colorcodes[index] != gc_color_code )
+ {
+ if ( gc_buffer_colorcodes[index] != gc_color_code )
+ {
+ gc_ops.paint_char( /* xx */ column,
+ /* yy */ row,
+ /* ch */ ' ',
+ /* attrs */ ATTR_NONE,
+ /* ch_previous */ 0,
+ /* attrs_previous */ 0 );
+ }
+ else
+ {
+ gc_ops.paint_char( /* xx */ column,
+ /* yy */ row,
+ /* ch */ ' ',
+ /* attrs */ ATTR_NONE,
+ /* ch_previous */ gc_buffer_characters[index],
+ /* attrs_previous */ gc_buffer_attributes[index] );
+ }
+
+ gc_buffer_attributes[index] = ATTR_NONE;
+ gc_buffer_characters[index] = ' ';
+ gc_buffer_colorcodes[index] = gc_color_code;
+ }
+ }
+ }
}
else
{
- simple_unlock(&gc_buffer_lock);
- splx(s);
-
gc_ops.scroll_down(num, top, bottom);
- }
- /* Now set the freed up lines to the background colour */
+ /* Now set the freed up lines to the background colour */
- gc_clear_screen(vinfo.v_columns - 1, top + num - 1, top, bottom, 1);
+ gc_clear_screen(vinfo.v_columns - 1, top + num - 1, top, bottom, 1);
+ }
}
static void
-gc_scroll_up(int num, int top, int bottom)
+gc_scroll_up(int num, unsigned int top, unsigned int bottom)
{
- spl_t s;
-
- s = splhigh();
- simple_lock(&gc_buffer_lock);
+ if (!gc_buffer_size) return;
if ( bottom <= gc_buffer_rows )
{
unsigned char colorcodesave = gc_color_code;
- unsigned long column, row;
- unsigned long index, jump;
+ uint32_t column, row;
+ uint32_t index, jump;
jump = num * gc_buffer_columns;
gc_buffer_attributes[index] = gc_buffer_attributes[index + jump];
gc_buffer_characters[index] = gc_buffer_characters[index + jump];
gc_buffer_colorcodes[index] = gc_buffer_colorcodes[index + jump];
-
}
}
}
gc_update_color(COLOR_CODE_GET(colorcodesave, FALSE), FALSE);
}
- simple_unlock(&gc_buffer_lock);
- splx(s);
+ /* Now set the freed up lines to the background colour */
+
+ for ( row = bottom - num ; row < bottom ; row++ )
+ {
+ index = row * gc_buffer_columns;
+
+ for ( column = 0 ; column < gc_buffer_columns ; index++, column++ )
+ {
+ if ( gc_buffer_attributes[index] != ATTR_NONE ||
+ gc_buffer_characters[index] != ' ' ||
+ gc_buffer_colorcodes[index] != gc_color_code )
+ {
+ if ( gc_buffer_colorcodes[index] != gc_color_code )
+ {
+ gc_ops.paint_char( /* xx */ column,
+ /* yy */ row,
+ /* ch */ ' ',
+ /* attrs */ ATTR_NONE,
+ /* ch_previous */ 0,
+ /* attrs_previous */ 0 );
+ }
+ else
+ {
+ gc_ops.paint_char( /* xx */ column,
+ /* yy */ row,
+ /* ch */ ' ',
+ /* attrs */ ATTR_NONE,
+ /* ch_previous */ gc_buffer_characters[index],
+ /* attrs_previous */ gc_buffer_attributes[index] );
+ }
+
+ gc_buffer_attributes[index] = ATTR_NONE;
+ gc_buffer_characters[index] = ' ';
+ gc_buffer_colorcodes[index] = gc_color_code;
+ }
+ }
+ }
}
else
{
- simple_unlock(&gc_buffer_lock);
- splx(s);
-
gc_ops.scroll_up(num, top, bottom);
- }
- /* Now set the freed up lines to the background colour */
+ /* Now set the freed up lines to the background colour */
- gc_clear_screen(0, bottom - num, top, bottom, 0);
+ gc_clear_screen(0, bottom - num, top, bottom, 0);
+ }
}
static void
-gc_show_cursor(int xx, int yy)
+gc_show_cursor(unsigned int xx, unsigned int yy)
{
- spl_t s;
-
- s = splhigh();
- simple_lock(&gc_buffer_lock);
-
if ( xx < gc_buffer_columns && yy < gc_buffer_rows )
{
- unsigned long index = (yy * gc_buffer_columns) + xx;
+ uint32_t index = (yy * gc_buffer_columns) + xx;
unsigned char attribute = gc_buffer_attributes[index];
unsigned char character = gc_buffer_characters[index];
unsigned char colorcode = gc_buffer_colorcodes[index];
unsigned char colorcodesave = gc_color_code;
- simple_unlock(&gc_buffer_lock);
- splx(s);
-
gc_update_color(COLOR_CODE_GET(colorcode, FALSE), TRUE );
gc_update_color(COLOR_CODE_GET(colorcode, TRUE ), FALSE);
}
else
{
- simple_unlock(&gc_buffer_lock);
- splx(s);
-
gc_ops.show_cursor(xx, yy);
}
}
static void
gc_update_color(int color, boolean_t fore)
{
+ assert(gc_ops.update_color);
+
gc_color_code = COLOR_CODE_SET(gc_color_code, color, fore);
gc_ops.update_color(color, fore);
}
-int
-vcputc(int l, int u, int c)
+void
+vcputc(__unused int l, __unused int u, int c)
{
- if ( gc_enabled || debug_mode )
- {
- gc_hide_cursor(gc_x, gc_y);
- gc_putchar(c);
- gc_show_cursor(gc_x, gc_y);
- }
+ if ( gc_initialized && ( gc_enabled || debug_mode ) )
+ {
+ spl_t s;
- return 0;
+ s = splhigh();
+#if defined(__i386__) || defined(__x86_64__)
+ x86_filter_TLB_coherency_interrupts(TRUE);
+#endif
+ VCPUTC_LOCK_LOCK();
+ if ( gc_enabled || debug_mode )
+ {
+ gc_hide_cursor(gc_x, gc_y);
+ gc_putchar(c);
+ gc_show_cursor(gc_x, gc_y);
+ }
+ VCPUTC_LOCK_UNLOCK();
+#if defined(__i386__) || defined(__x86_64__)
+ x86_filter_TLB_coherency_interrupts(FALSE);
+#endif
+ splx(s);
+ }
}
/*
*/
static unsigned char vc_color_index_table[33] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 };
-
-static unsigned long vc_colors[8][3] = {
- { 0xFFFFFFFF, 0x00000000, 0x00000000 }, /* black */
- { 0x23232323, 0x7C007C00, 0x00FF0000 }, /* red */
- { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00 }, /* green */
- { 0x05050505, 0x7FE07FE0, 0x00FFFF00 }, /* yellow */
- { 0xd2d2d2d2, 0x001f001f, 0x000000FF}, /* blue */
-// { 0x80808080, 0x31933193, 0x00666699 }, /* blue */
- { 0x18181818, 0x7C1F7C1F, 0x00FF00FF }, /* magenta */
- { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF }, /* cyan */
- { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF } /* white */
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2 };
+
+static uint32_t vc_colors[8][4] = {
+ { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }, /* black */
+ { 0x23232323, 0x7C007C00, 0x00FF0000, 0x3FF00000 }, /* red */
+ { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00, 0x000FFC00 }, /* green */
+ { 0x05050505, 0x7FE07FE0, 0x00FFFF00, 0x3FFFFC00 }, /* yellow */
+ { 0xd2d2d2d2, 0x001f001f, 0x000000FF, 0x000003FF }, /* blue */
+// { 0x80808080, 0x31933193, 0x00666699, 0x00000000 }, /* blue */
+ { 0x18181818, 0x7C1F7C1F, 0x00FF00FF, 0x3FF003FF }, /* magenta */
+ { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF, 0x000FFFFF }, /* cyan */
+ { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF, 0x3FFFFFFF } /* white */
};
-static unsigned long vc_color_fore = 0;
-static unsigned long vc_color_back = 0;
+static uint32_t vc_color_fore = 0;
+static uint32_t vc_color_back = 0;
/*
* New Rendering code from Michel Pollet
static unsigned char *vc_rendered_font = NULL;
/* Rendered Font Size */
-static unsigned long vc_rendered_font_size = 0;
+static uint32_t vc_rendered_font_size = 0;
/* Size of a character in the table (bytes) */
static int vc_rendered_char_size = 0;
#define REN_MAX_DEPTH 32
static unsigned char vc_rendered_char[ISO_CHAR_HEIGHT * ((REN_MAX_DEPTH / 8) * ISO_CHAR_WIDTH)];
-static void vc_clear_screen(int xx, int yy, int scrreg_top, int scrreg_bottom, int which);
-static void vc_enable(boolean_t enable);
-static void vc_initialize(struct vc_info * vinfo_p);
-static void vc_paint_char(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
-static void vc_paint_char_8(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
-static void vc_paint_char_16(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
-static void vc_paint_char_32(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous);
-static void vc_render_char(unsigned char ch, unsigned char *renderptr, short newdepth);
-static void vc_render_font(short newdepth);
-static void vc_reverse_cursor(int xx, int yy);
-static void vc_scroll_down(int num, int scrreg_top, int scrreg_bottom);
-static void vc_scroll_up(int num, int scrreg_top, int scrreg_bottom);
-static void vc_update_color(int color, boolean_t fore);
+static void
+internal_set_progressmeter(int new_value);
+static void
+internal_enable_progressmeter(int new_value);
+
+enum
+{
+ kProgressMeterOff = FALSE,
+ kProgressMeterUser = TRUE,
+ kProgressMeterKernel = 3,
+};
+enum
+{
+ kProgressMeterMax = 1024,
+ kProgressMeterEnd = 512,
+};
+
+
+static boolean_t vc_progress_white =
+#ifdef CONFIG_VC_PROGRESS_WHITE
+ TRUE;
+#else /* !CONFIG_VC_PROGRESS_WHITE */
+ FALSE;
+#endif /* !CONFIG_VC_PROGRESS_WHITE */
+
+static int vc_acquire_delay = kProgressAcquireDelay;
static void
-vc_clear_screen(int xx, int yy, int scrreg_top, int scrreg_bottom, int which)
+vc_clear_screen(unsigned int xx, unsigned int yy, unsigned int scrreg_top,
+ unsigned int scrreg_bottom, int which)
{
- unsigned long *p, *endp, *row;
+ uint32_t *p, *endp, *row;
int linelongs, col;
int rowline, rowlongs;
rowline = vinfo.v_rowscanbytes >> 2;
rowlongs = vinfo.v_rowbytes >> 2;
- p = (unsigned long*) vinfo.v_baseaddr;
- endp = (unsigned long*) vinfo.v_baseaddr;
+ p = (uint32_t*) vinfo.v_baseaddr;
+ endp = (uint32_t*) vinfo.v_baseaddr;
switch (which) {
case 0: /* To end of screen */
}
static void
-vc_enable(boolean_t enable)
+vc_render_char(unsigned char ch, unsigned char *renderptr, short newdepth)
{
- if ( enable )
- {
- vc_render_font(vinfo.v_depth);
- }
-}
+ union {
+ unsigned char *charptr;
+ unsigned short *shortptr;
+ uint32_t *longptr;
+ } current; /* current place in rendered font, multiple types. */
+ unsigned char *theChar; /* current char in iso_font */
+ int line;
-static void
-vc_initialize(struct vc_info * vinfo_p)
-{
- vinfo.v_rows = vinfo.v_height / ISO_CHAR_HEIGHT;
- vinfo.v_columns = vinfo.v_width / ISO_CHAR_WIDTH;
- vinfo.v_rowscanbytes = (vinfo.v_depth / 8) * vinfo.v_width;
-}
+ current.charptr = renderptr;
+ theChar = iso_font + (ch * ISO_CHAR_HEIGHT);
-static void
-vc_paint_char(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous)
-{
- if( !vinfo.v_depth)
- return;
+ for (line = 0; line < ISO_CHAR_HEIGHT; line++) {
+ unsigned char mask = 1;
+ do {
+ switch (newdepth) {
+ case 8:
+ *current.charptr++ = (*theChar & mask) ? 0xFF : 0;
+ break;
+ case 16:
+ *current.shortptr++ = (*theChar & mask) ? 0xFFFF : 0;
+ break;
- switch( vinfo.v_depth) {
- case 8:
- vc_paint_char_8(xx, yy, ch, attrs, ch_previous, attrs_previous);
- break;
- case 16:
- vc_paint_char_16(xx, yy, ch, attrs, ch_previous, attrs_previous);
- break;
- case 32:
- vc_paint_char_32(xx, yy, ch, attrs, ch_previous, attrs_previous);
- break;
+ case 30:
+ case 32:
+ *current.longptr++ = (*theChar & mask) ? 0xFFFFFFFF : 0;
+ break;
+ }
+ mask <<= 1;
+ } while (mask); /* while the single bit drops to the right */
+ theChar++;
}
}
static void
-vc_paint_char_8(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous)
+vc_paint_char_8(unsigned int xx, unsigned int yy, unsigned char ch, int attrs,
+ __unused unsigned char ch_previous, __unused int attrs_previous)
{
- unsigned long *theChar;
- unsigned long *where;
+ uint32_t *theChar;
+ uint32_t *where;
int i;
if (vc_rendered_font) {
- theChar = (unsigned long*)(vc_rendered_font + (ch * vc_rendered_char_size));
+ theChar = (uint32_t*)(vc_rendered_font + (ch * vc_rendered_char_size));
} else {
vc_render_char(ch, vc_rendered_char, 8);
- theChar = (unsigned long*)(vc_rendered_char);
+ theChar = (uint32_t*)(vc_rendered_char);
}
- where = (unsigned long*)(vinfo.v_baseaddr +
+ where = (uint32_t*)(vinfo.v_baseaddr +
(yy * ISO_CHAR_HEIGHT * vinfo.v_rowbytes) +
(xx * ISO_CHAR_WIDTH));
if (!attrs) for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* No attr? FLY !*/
- unsigned long *store = where;
+ uint32_t *store = where;
int x;
for (x = 0; x < 2; x++) {
- unsigned long val = *theChar++;
+ uint32_t val = *theChar++;
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
}
- where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
+ where = (uint32_t*)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* a little slower */
- unsigned long *store = where, lastpixel = 0;
+ uint32_t *store = where, lastpixel = 0;
int x;
for (x = 0 ; x < 2; x++) {
- unsigned long val = *theChar++, save = val;
+ uint32_t val = *theChar++, save = val;
if (attrs & ATTR_BOLD) { /* bold support */
if (lastpixel && !(save & 0xFF000000))
val |= 0xff000000;
lastpixel = save & 0xff;
}
- where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
+ where = (uint32_t*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void
-vc_paint_char_16(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous)
+vc_paint_char_16(unsigned int xx, unsigned int yy, unsigned char ch, int attrs,
+ __unused unsigned char ch_previous,
+ __unused int attrs_previous)
{
- unsigned long *theChar;
- unsigned long *where;
+ uint32_t *theChar;
+ uint32_t *where;
int i;
if (vc_rendered_font) {
- theChar = (unsigned long*)(vc_rendered_font + (ch * vc_rendered_char_size));
+ theChar = (uint32_t*)(vc_rendered_font + (ch * vc_rendered_char_size));
} else {
vc_render_char(ch, vc_rendered_char, 16);
- theChar = (unsigned long*)(vc_rendered_char);
+ theChar = (uint32_t*)(vc_rendered_char);
}
- where = (unsigned long*)(vinfo.v_baseaddr +
+ where = (uint32_t*)(vinfo.v_baseaddr +
(yy * ISO_CHAR_HEIGHT * vinfo.v_rowbytes) +
(xx * ISO_CHAR_WIDTH * 2));
if (!attrs) for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* No attrs ? FLY ! */
- unsigned long *store = where;
+ uint32_t *store = where;
int x;
for (x = 0; x < 4; x++) {
- unsigned long val = *theChar++;
+ uint32_t val = *theChar++;
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
}
- where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
+ where = (uint32_t*)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* a little bit slower */
- unsigned long *store = where, lastpixel = 0;
+ uint32_t *store = where, lastpixel = 0;
int x;
for (x = 0 ; x < 4; x++) {
- unsigned long val = *theChar++, save = val;
+ uint32_t val = *theChar++, save = val;
if (attrs & ATTR_BOLD) { /* bold support */
if (save == 0xFFFF0000) val |= 0xFFFF;
else if (lastpixel && !(save & 0xFFFF0000))
lastpixel = save & 0x7fff;
}
- where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
+ where = (uint32_t*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void
-vc_paint_char_32(int xx, int yy, unsigned char ch, int attrs, unsigned char ch_previous, int attrs_previous)
+vc_paint_char_32(unsigned int xx, unsigned int yy, unsigned char ch, int attrs,
+ unsigned char ch_previous, int attrs_previous)
{
- unsigned long *theChar;
- unsigned long *theCharPrevious;
- unsigned long *where;
+ uint32_t *theChar;
+ uint32_t *theCharPrevious;
+ uint32_t *where;
int i;
if (vc_rendered_font) {
- theChar = (unsigned long*)(vc_rendered_font + (ch * vc_rendered_char_size));
- theCharPrevious = (unsigned long*)(vc_rendered_font + (ch_previous * vc_rendered_char_size));
+ theChar = (uint32_t*)(vc_rendered_font + (ch * vc_rendered_char_size));
+ theCharPrevious = (uint32_t*)(vc_rendered_font + (ch_previous * vc_rendered_char_size));
} else {
vc_render_char(ch, vc_rendered_char, 32);
- theChar = (unsigned long*)(vc_rendered_char);
+ theChar = (uint32_t*)(vc_rendered_char);
theCharPrevious = NULL;
}
if (!ch_previous) {
if (attrs_previous) {
theCharPrevious = NULL;
}
- where = (unsigned long*)(vinfo.v_baseaddr +
+ where = (uint32_t*)(vinfo.v_baseaddr +
(yy * ISO_CHAR_HEIGHT * vinfo.v_rowbytes) +
(xx * ISO_CHAR_WIDTH * 4));
if (!attrs) for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* No attrs ? FLY ! */
- unsigned long *store = where;
+ uint32_t *store = where;
int x;
for (x = 0; x < 8; x++) {
- unsigned long val = *theChar++;
+ uint32_t val = *theChar++;
if (theCharPrevious == NULL || val != *theCharPrevious++ ) {
val = (vc_color_back & ~val) | (vc_color_fore & val);
*store++ = val;
}
}
- where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
+ where = (uint32_t *)(((unsigned char*)where)+vinfo.v_rowbytes);
} else for (i = 0; i < ISO_CHAR_HEIGHT; i++) { /* a little slower */
- unsigned long *store = where, lastpixel = 0;
+ uint32_t *store = where, lastpixel = 0;
int x;
for (x = 0 ; x < 8; x++) {
- unsigned long val = *theChar++, save = val;
+ uint32_t val = *theChar++, save = val;
if (attrs & ATTR_BOLD) { /* bold support */
if (lastpixel && !save)
val = 0xFFFFFFFF;
lastpixel = save;
}
- where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
+ where = (uint32_t*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void
-vc_render_char(unsigned char ch, unsigned char *renderptr, short newdepth)
+vc_paint_char(unsigned int xx, unsigned int yy, unsigned char ch, int attrs,
+ unsigned char ch_previous, int attrs_previous)
{
- union {
- unsigned char *charptr;
- unsigned short *shortptr;
- unsigned long *longptr;
- } current; /* current place in rendered font, multiple types. */
+ if(!vinfo.v_depth)
+ return;
- unsigned char *theChar; /* current char in iso_font */
+ switch(vinfo.v_depth) {
+ case 8:
+ vc_paint_char_8(xx, yy, ch, attrs, ch_previous, attrs_previous);
+ break;
+ case 16:
+ vc_paint_char_16(xx, yy, ch, attrs, ch_previous,
+ attrs_previous);
+ break;
+ case 30:
+ case 32:
+ vc_paint_char_32(xx, yy, ch, attrs, ch_previous,
+ attrs_previous);
+ break;
+ }
+}
- int line;
+static void
+vc_render_font(short newdepth)
+{
+ static short olddepth = 0;
- current.charptr = renderptr;
- theChar = iso_font + (ch * ISO_CHAR_HEIGHT);
-
- for (line = 0; line < ISO_CHAR_HEIGHT; line++) {
- unsigned char mask = 1;
- do {
- switch (newdepth) {
- case 8:
- *current.charptr++ = (*theChar & mask) ? 0xFF : 0;
- break;
- case 16:
- *current.shortptr++ = (*theChar & mask) ? 0xFFFF : 0;
- break;
-
- case 32:
- *current.longptr++ = (*theChar & mask) ? 0xFFFFFFFF : 0;
- break;
- }
- mask <<= 1;
- } while (mask); /* while the single bit drops to the right */
- theChar++;
- }
-}
-
-static void
-vc_render_font(short newdepth)
-{
- static short olddepth = 0;
-
- int charindex; /* index in ISO font */
+ int charindex; /* index in ISO font */
+ unsigned char *rendered_font;
+ unsigned int rendered_font_size;
+ int rendered_char_size;
+ spl_t s;
if (vm_initialized == FALSE) {
return; /* nothing to do */
if (olddepth == newdepth && vc_rendered_font) {
return; /* nothing to do */
}
- if (vc_rendered_font) {
- kfree(vc_rendered_font, vc_rendered_font_size);
+
+ s = splhigh();
+ VCPUTC_LOCK_LOCK();
+
+ rendered_font = vc_rendered_font;
+ rendered_font_size = vc_rendered_font_size;
+ rendered_char_size = vc_rendered_char_size;
+
+ vc_rendered_font = NULL;
+ vc_rendered_font_size = 0;
+ vc_rendered_char_size = 0;
+
+ VCPUTC_LOCK_UNLOCK();
+ splx(s);
+
+ if (rendered_font) {
+ kfree(rendered_font, rendered_font_size);
+ rendered_font = NULL;
}
- vc_rendered_char_size = ISO_CHAR_HEIGHT * ((newdepth / 8) * ISO_CHAR_WIDTH);
- vc_rendered_font_size = (ISO_CHAR_MAX-ISO_CHAR_MIN+1) * vc_rendered_char_size;
- vc_rendered_font = (unsigned char *) kalloc(vc_rendered_font_size);
+ if (newdepth) {
+ rendered_char_size = ISO_CHAR_HEIGHT * (((newdepth + 7) / 8) * ISO_CHAR_WIDTH);
+ rendered_font_size = (ISO_CHAR_MAX-ISO_CHAR_MIN+1) * rendered_char_size;
+ rendered_font = (unsigned char *) kalloc(rendered_font_size);
+ }
- if (vc_rendered_font == NULL) {
- vc_rendered_font_size = 0;
+ if (rendered_font == NULL) {
return;
}
for (charindex = ISO_CHAR_MIN; charindex <= ISO_CHAR_MAX; charindex++) {
- vc_render_char(charindex, vc_rendered_font + (charindex * vc_rendered_char_size), newdepth);
+ vc_render_char(charindex, rendered_font + (charindex * rendered_char_size), newdepth);
}
olddepth = newdepth;
+
+ s = splhigh();
+ VCPUTC_LOCK_LOCK();
+
+ vc_rendered_font = rendered_font;
+ vc_rendered_font_size = rendered_font_size;
+ vc_rendered_char_size = rendered_char_size;
+
+ VCPUTC_LOCK_UNLOCK();
+ splx(s);
+}
+
+static void
+vc_enable(boolean_t enable)
+{
+ vc_render_font(enable ? vinfo.v_depth : 0);
}
static void
-vc_reverse_cursor(int xx, int yy)
+vc_reverse_cursor(unsigned int xx, unsigned int yy)
{
- unsigned long *where;
+ uint32_t *where;
int line, col;
if(!vinfo.v_depth)
return;
- where = (unsigned long*)(vinfo.v_baseaddr +
+ where = (uint32_t*)(vinfo.v_baseaddr +
(yy * ISO_CHAR_HEIGHT * vinfo.v_rowbytes) +
(xx /** ISO_CHAR_WIDTH*/ * vinfo.v_depth));
for (line = 0; line < ISO_CHAR_HEIGHT; line++) {
where[col] = ~where[col];
break;
}
- where = (unsigned long*)(((unsigned char*)where)+vinfo.v_rowbytes);
+ where = (uint32_t*)(((unsigned char*)where)+vinfo.v_rowbytes);
}
}
static void
-vc_scroll_down(int num, int scrreg_top, int scrreg_bottom)
+vc_scroll_down(int num, unsigned int scrreg_top, unsigned int scrreg_bottom)
{
- unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
+ uint32_t *from, *to, linelongs, i, line, rowline, rowscanline;
if(!vinfo.v_depth)
return;
rowline = vinfo.v_rowbytes >> 2;
rowscanline = vinfo.v_rowscanbytes >> 2;
- to = (unsigned long *) vinfo.v_baseaddr + (linelongs * scrreg_bottom)
+ to = (uint32_t *) vinfo.v_baseaddr + (linelongs * scrreg_bottom)
- (rowline - rowscanline);
from = to - (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
/*
* Only copy what is displayed
*/
- video_scroll_down((unsigned int) from,
- (unsigned int) (from-(vinfo.v_rowscanbytes >> 2)),
- (unsigned int) to);
+ video_scroll_down(from,
+ (from-(vinfo.v_rowscanbytes >> 2)),
+ to);
from -= rowline;
to -= rowline;
}
static void
-vc_scroll_up(int num, int scrreg_top, int scrreg_bottom)
+vc_scroll_up(int num, unsigned int scrreg_top, unsigned int scrreg_bottom)
{
- unsigned long *from, *to, linelongs, i, line, rowline, rowscanline;
+ uint32_t *from, *to, linelongs, i, line, rowline, rowscanline;
if(!vinfo.v_depth)
return;
rowline = vinfo.v_rowbytes >> 2;
rowscanline = vinfo.v_rowscanbytes >> 2;
- to = (unsigned long *) vinfo.v_baseaddr + (scrreg_top * linelongs);
+ to = (uint32_t *) vinfo.v_baseaddr + (scrreg_top * linelongs);
from = to + (linelongs * num); /* handle multiple line scroll (Michel Pollet) */
i = (scrreg_bottom - scrreg_top) - num;
/*
* Only copy what is displayed
*/
- video_scroll_up((unsigned int) from,
- (unsigned int) (from+(vinfo.v_rowscanbytes >> 2)),
- (unsigned int) to);
+ video_scroll_up(from,
+ (from+(vinfo.v_rowscanbytes >> 2)),
+ to);
from += rowline;
to += rowline;
* --------------------------------------
*/
-struct vc_progress_element {
- unsigned int version;
- unsigned int flags;
- unsigned int time;
- unsigned char count;
- unsigned char res[3];
- int width;
- int height;
- int dx;
- int dy;
- int transparent;
- unsigned int res2[3];
- unsigned char data[0];
-};
-typedef struct vc_progress_element vc_progress_element;
-
static vc_progress_element * vc_progress;
-static const unsigned char * vc_progress_data;
+enum { kMaxProgressData = 3 };
+static const unsigned char * vc_progress_data[kMaxProgressData];
static const unsigned char * vc_progress_alpha;
static boolean_t vc_progress_enable;
static const unsigned char * vc_clut;
static const unsigned char * vc_clut8;
static unsigned char vc_revclut8[256];
static uint32_t vc_progress_interval;
+static uint32_t vc_progress_count;
+static uint32_t vc_progress_angle;
static uint64_t vc_progress_deadline;
static thread_call_data_t vc_progress_call;
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 void vc_blit_rect( int x, int y, int width, int height,
- const unsigned char * dataPtr, const unsigned char * alphaPtr,
- void * backBuffer, boolean_t save, boolean_t static_alpha );
-static void vc_blit_rect_8( int x, int y, int width, int height,
- const unsigned char * dataPtr, const unsigned char * alphaPtr,
- unsigned char * backBuffer, boolean_t save, boolean_t static_alpha );
-static void vc_blit_rect_16( int x, int y, int width, int height,
- const unsigned char * dataPtr, const unsigned char * alphaPtr,
- unsigned short * backBuffer, boolean_t save, boolean_t static_alpha );
-static void vc_blit_rect_32( int x, int y, int width, int height,
- const unsigned char * dataPtr, const unsigned char * alphaPtr,
- unsigned int * backBuffer, boolean_t save, boolean_t static_alpha );
-extern void vc_display_icon( vc_progress_element * desc, const unsigned char * data );
-extern void vc_progress_initialize( vc_progress_element * desc, const unsigned char * data, const unsigned char * clut );
-static void vc_progress_set( boolean_t enable, uint32_t delay );
-static void vc_progress_task( void * arg0, void * arg );
+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 void * vc_progressmeter_backbuffer;
+static boolean_t vc_progressmeter_hold;
+static uint32_t vc_progressmeter_diskspeed = 256;
+
+
+enum {
+ kSave = 0x10,
+ kDataIndexed = 0x20,
+ kDataAlpha = 0x40,
+ kDataBack = 0x80,
+ kDataRotate = 0x03,
+ kDataRotate0 = 0,
+ kDataRotate90 = 1,
+ kDataRotate180 = 2,
+ kDataRotate270 = 3
+};
-static void vc_blit_rect( int x, int y,
- int width, int height,
- const unsigned char * dataPtr,
- const unsigned char * alphaPtr,
- void * backBuffer,
- boolean_t save, boolean_t static_alpha )
+static void vc_blit_rect(int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ void * backBuffer,
+ unsigned int flags);
+static void vc_blit_rect_8(int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ unsigned char * backBuffer,
+ unsigned int flags);
+static void vc_blit_rect_16(int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ unsigned short * backBuffer,
+ unsigned int flags);
+static void vc_blit_rect_32(int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ unsigned int * backBuffer,
+ unsigned int flags);
+static void vc_blit_rect_30(int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ unsigned int * backBuffer,
+ unsigned int flags);
+static void vc_progress_task( void * arg0, void * arg );
+static void vc_progressmeter_task( void * arg0, void * arg );
+
+static void vc_blit_rect(int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ 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:
if( vc_clut8 == vc_clut)
- vc_blit_rect_8( x, y, width, height, dataPtr, alphaPtr, (unsigned char *) backBuffer, save, static_alpha );
+ vc_blit_rect_8( x, y, bx, width, height, sourceRow, backRow, dataPtr, (unsigned char *) backBuffer, flags );
break;
case 16:
- vc_blit_rect_16( x, y, width, height, dataPtr, alphaPtr, (unsigned short *) backBuffer, save, static_alpha );
+ vc_blit_rect_16( x, y, bx, width, height, sourceRow, backRow, dataPtr, (unsigned short *) backBuffer, flags );
break;
case 32:
- vc_blit_rect_32( x, y, width, height, dataPtr, alphaPtr, (unsigned int *) backBuffer, save, static_alpha );
+ vc_blit_rect_32( x, y, bx, width, height, sourceRow, backRow, dataPtr, (unsigned int *) backBuffer, flags );
+ break;
+ case 30:
+ vc_blit_rect_30( x, y, bx, width, height, sourceRow, backRow, dataPtr, (unsigned int *) backBuffer, flags );
break;
}
}
-static void vc_blit_rect_8( int x, int y,
- int width, int height,
- const unsigned char * dataPtr,
- const unsigned char * alphaPtr,
- unsigned char * backPtr,
- boolean_t save, boolean_t static_alpha )
+static void
+vc_blit_rect_8(int x, int y, __unused int bx,
+ int width, int height,
+ int sourceRow, __unused int backRow,
+ const unsigned char * dataPtr,
+ __unused unsigned char * backBuffer,
+ __unused unsigned int flags)
{
- volatile unsigned char * dst;
+ volatile unsigned short * dst;
int line, col;
- unsigned int data;
-
- dst = (unsigned char *)(vinfo.v_baseaddr +
- (y * vinfo.v_rowbytes) +
- (x));
-
- for( line = 0; line < height; line++) {
- for( col = 0; col < width; col++) {
- data = 0;
- if( dataPtr != 0) data = *dataPtr++;
- else if( alphaPtr != 0) data = vc_revclut8[*alphaPtr++];
- *(dst + col) = data;
- }
- dst = (volatile unsigned char *) (((int)dst) + vinfo.v_rowbytes);
+ unsigned int data = 0, out = 0;
+ int sx, sy, a, b, c, d;
+ int scale = 0x10000;
+
+ a = vc_rotate_matr[kDataRotate & flags][0][0] * scale;
+ b = vc_rotate_matr[kDataRotate & flags][0][1] * scale;
+ c = vc_rotate_matr[kDataRotate & flags][1][0] * scale;
+ d = vc_rotate_matr[kDataRotate & flags][1][1] * scale;
+ sx = ((a + b) < 0) ? ((width * scale) - 0x8000) : 0;
+ sy = ((c + d) < 0) ? ((height * scale) - 0x8000) : 0;
+
+ if (!sourceRow) data = (unsigned int)(uintptr_t)dataPtr;
+ else if (1 == sourceRow) a = 0;
+
+ dst = (volatile unsigned short *) (vinfo.v_baseaddr +
+ (y * vinfo.v_rowbytes) +
+ (x * 4));
+
+ for( line = 0; line < height; line++)
+ {
+ for( col = 0; col < width; col++)
+ {
+ if (sourceRow) data = dataPtr[((sx + (col * a) + (line * b)) >> 16)
+ + sourceRow * (((sy + (col * c) + (line * d)) >> 16))];
+ if (kDataAlpha & flags)
+ out = vc_revclut8[data];
+ else
+ out = data;
+ *(dst + col) = out;
+ }
+ dst = (volatile unsigned short *) (((volatile char*)dst) + vinfo.v_rowbytes);
}
}
-static void vc_blit_rect_16( int x, int y,
- int width, int height,
- const unsigned char * dataPtr,
- const unsigned char * alphaPtr,
- unsigned short * backPtr,
- boolean_t save, boolean_t static_alpha )
+/* For ARM, 16-bit is 565 (RGB); it is 1555 (XRGB) on other platforms */
+
+#define CLUT_MASK_R 0xf8
+#define CLUT_MASK_G 0xf8
+#define CLUT_MASK_B 0xf8
+#define CLUT_SHIFT_R << 7
+#define CLUT_SHIFT_G << 2
+#define CLUT_SHIFT_B >> 3
+#define MASK_R 0x7c00
+#define MASK_G 0x03e0
+#define MASK_B 0x001f
+#define MASK_R_8 0x3fc00
+#define MASK_G_8 0x01fe0
+#define MASK_B_8 0x000ff
+
+static void vc_blit_rect_16( int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ unsigned short * backPtr,
+ unsigned int flags)
{
volatile unsigned short * dst;
int line, col;
- unsigned int data, index, alpha, back;
-
- dst = (volatile unsigned short *)(vinfo.v_baseaddr +
+ unsigned int data = 0, out = 0, back = 0;
+ int sx, sy, a, b, c, d;
+ int scale = 0x10000;
+
+ a = vc_rotate_matr[kDataRotate & flags][0][0] * scale;
+ b = vc_rotate_matr[kDataRotate & flags][0][1] * scale;
+ c = vc_rotate_matr[kDataRotate & flags][1][0] * scale;
+ d = vc_rotate_matr[kDataRotate & flags][1][1] * scale;
+ sx = ((a + b) < 0) ? ((width * scale) - 0x8000) : 0;
+ sy = ((c + d) < 0) ? ((height * scale) - 0x8000) : 0;
+
+ if (!sourceRow) data = (unsigned int)(uintptr_t)dataPtr;
+ else if (1 == sourceRow) a = 0;
+
+ if (backPtr)
+ backPtr += bx;
+ dst = (volatile unsigned short *) (vinfo.v_baseaddr +
(y * vinfo.v_rowbytes) +
(x * 2));
- for( line = 0; line < height; line++) {
- for( col = 0; col < width; col++) {
- if( dataPtr != 0) {
- index = *dataPtr++;
- index *= 3;
+ for( line = 0; line < height; line++)
+ {
+ for( col = 0; col < width; col++)
+ {
+ 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);
+ *backPtr++ = back;
+ } else
+ back = *backPtr++;
}
+ if (kDataIndexed & flags) {
+ out = ( (CLUT_MASK_R & (vc_clut[data*3 + 0])) CLUT_SHIFT_R)
+ | ( (CLUT_MASK_G & (vc_clut[data*3 + 1])) CLUT_SHIFT_G)
+ | ( (CLUT_MASK_B & (vc_clut[data*3 + 2])) CLUT_SHIFT_B);
+ } else if (kDataAlpha & flags) {
+ out = (((((back & MASK_R) * data) + MASK_R_8) >> 8) & MASK_R)
+ | (((((back & MASK_G) * data) + MASK_G_8) >> 8) & MASK_G)
+ | (((((back & MASK_B) * data) + MASK_B_8) >> 8) & MASK_B);
+ if (vc_progress_white) out += (((0xff - data) & CLUT_MASK_R) CLUT_SHIFT_R)
+ | (((0xff - data) & CLUT_MASK_G) CLUT_SHIFT_G)
+ | (((0xff - data) & CLUT_MASK_B) CLUT_SHIFT_B);
+ } else if (kDataBack & flags)
+ out = back;
+ else
+ out = data;
+ *(dst + col) = out;
+ }
+ dst = (volatile unsigned short *) (((volatile char*)dst) + vinfo.v_rowbytes);
+ if (backPtr)
+ backPtr += backRow - width;
+ }
+}
- if( alphaPtr && backPtr) {
-
- alpha = *alphaPtr++;
- data = 0;
- if( dataPtr != 0) {
- if( vc_clut[index + 0] > alpha)
- data |= (((vc_clut[index + 0] - alpha) & 0xf8) << 7);
- if( vc_clut[index + 1] > alpha)
- data |= (((vc_clut[index + 1] - alpha) & 0xf8) << 2);
- if( vc_clut[index + 2] > alpha)
- data |= (((vc_clut[index + 2] - alpha) & 0xf8) >> 3);
- }
- if( save) {
- back = *(dst + col);
- if ( !static_alpha)
- *backPtr++ = back;
- back = (((((back & 0x7c00) * alpha) + 0x3fc00) >> 8) & 0x7c00)
- | (((((back & 0x03e0) * alpha) + 0x01fe0) >> 8) & 0x03e0)
- | (((((back & 0x001f) * alpha) + 0x000ff) >> 8) & 0x001f);
- if ( static_alpha)
- *backPtr++ = back;
- } else {
- back = *backPtr++;
- if ( !static_alpha) {
- back = (((((back & 0x7c00) * alpha) + 0x3fc00) >> 8) & 0x7c00)
- | (((((back & 0x03e0) * alpha) + 0x01fe0) >> 8) & 0x03e0)
- | (((((back & 0x001f) * alpha) + 0x000ff) >> 8) & 0x001f);
- }
- }
-
- data += back;
-
- } else
- if( dataPtr != 0) {
- data = ( (0xf8 & (vc_clut[index + 0])) << 7)
- | ( (0xf8 & (vc_clut[index + 1])) << 2)
- | ( (0xf8 & (vc_clut[index + 2])) >> 3);
- }
+static void vc_blit_rect_32(int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ unsigned int * backPtr,
+ unsigned int flags)
+{
+ volatile unsigned int * dst;
+ int line, col;
+ unsigned int data = 0, out = 0, back = 0;
+ int sx, sy, a, b, c, d;
+ int scale = 0x10000;
+
+ a = vc_rotate_matr[kDataRotate & flags][0][0] * scale;
+ b = vc_rotate_matr[kDataRotate & flags][0][1] * scale;
+ c = vc_rotate_matr[kDataRotate & flags][1][0] * scale;
+ d = vc_rotate_matr[kDataRotate & flags][1][1] * scale;
+ sx = ((a + b) < 0) ? ((width * scale) - 0x8000) : 0;
+ sy = ((c + d) < 0) ? ((height * scale) - 0x8000) : 0;
+
+ if (!sourceRow) data = (unsigned int)(uintptr_t)dataPtr;
+ else if (1 == sourceRow) a = 0;
+
+ if (backPtr)
+ backPtr += bx;
+ dst = (volatile unsigned int *) (vinfo.v_baseaddr +
+ (y * vinfo.v_rowbytes) +
+ (x * 4));
- *(dst + col) = data;
- }
- dst = (volatile unsigned short *) (((int)dst) + vinfo.v_rowbytes);
+ for( line = 0; line < height; line++)
+ {
+ for( col = 0; col < width; col++)
+ {
+ 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);
+ *backPtr++ = back;
+ } else
+ back = *backPtr++;
+ }
+ if (kDataIndexed & flags) {
+ out = (vc_clut[data*3 + 0] << 16)
+ | (vc_clut[data*3 + 1] << 8)
+ | (vc_clut[data*3 + 2]);
+ } else if (kDataAlpha & flags) {
+ out = (((((back & 0x00ff00ff) * data) + 0x00ff00ff) >> 8) & 0x00ff00ff)
+ | (((((back & 0x0000ff00) * data) + 0x0000ff00) >> 8) & 0x0000ff00);
+ if (vc_progress_white) out += ((0xff - data) << 16)
+ | ((0xff - data) << 8)
+ | (0xff - data);
+ } else if (kDataBack & flags)
+ out = back;
+ else
+ out = data;
+ *(dst + col) = out;
+ }
+ dst = (volatile unsigned int *) (((volatile char*)dst) + vinfo.v_rowbytes);
+ if (backPtr)
+ backPtr += backRow - width;
}
}
-static void vc_blit_rect_32( int x, int y,
- int width, int height,
- const unsigned char * dataPtr,
- const unsigned char * alphaPtr,
- unsigned int * backPtr,
- boolean_t save, boolean_t static_alpha )
+static void vc_blit_rect_30(int x, int y, int bx,
+ int width, int height,
+ int sourceRow, int backRow,
+ const unsigned char * dataPtr,
+ unsigned int * backPtr,
+ unsigned int flags)
{
volatile unsigned int * dst;
int line, col;
- unsigned int data, index, alpha, back;
-
+ unsigned int data = 0, out = 0, back = 0;
+ unsigned long long exp;
+ int sx, sy, a, b, c, d;
+ int scale = 0x10000;
+
+ a = vc_rotate_matr[kDataRotate & flags][0][0] * scale;
+ b = vc_rotate_matr[kDataRotate & flags][0][1] * scale;
+ c = vc_rotate_matr[kDataRotate & flags][1][0] * scale;
+ d = vc_rotate_matr[kDataRotate & flags][1][1] * scale;
+ sx = ((a + b) < 0) ? ((width * scale) - 0x8000) : 0;
+ sy = ((c + d) < 0) ? ((height * scale) - 0x8000) : 0;
+
+ if (!sourceRow) data = (unsigned int)(uintptr_t)dataPtr;
+ else if (1 == sourceRow) a = 0;
+
+ if (backPtr)
+ backPtr += bx;
dst = (volatile unsigned int *) (vinfo.v_baseaddr +
(y * vinfo.v_rowbytes) +
(x * 4));
- for( line = 0; line < height; line++) {
- for( col = 0; col < width; col++) {
- if( dataPtr != 0) {
- index = *dataPtr++;
- index *= 3;
+ for( line = 0; line < height; line++)
+ {
+ for( col = 0; col < width; col++)
+ {
+ 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);
+ *backPtr++ = back;
+ } else
+ back = *backPtr++;
}
+ if (kDataIndexed & flags) {
+ out = (vc_clut[data*3 + 0] << 22)
+ | (vc_clut[data*3 + 1] << 12)
+ | (vc_clut[data*3 + 2] << 2);
+ } else if (kDataAlpha & flags) {
+ exp = back;
+ exp = (((((exp & 0x3FF003FF) * data) + 0x0FF000FF) >> 8) & 0x3FF003FF)
+ | (((((exp & 0x000FFC00) * data) + 0x0003FC00) >> 8) & 0x000FFC00);
+ out = (unsigned int)exp;
+ if (vc_progress_white) out += ((0xFF - data) << 22)
+ | ((0xFF - data) << 12)
+ | ((0xFF - data) << 2);
+ } else if (kDataBack & flags)
+ out = back;
+ else
+ out = data;
+ *(dst + col) = out;
+ }
+ dst = (volatile unsigned int *) (((volatile char*)dst) + vinfo.v_rowbytes);
+ if (backPtr)
+ backPtr += backRow - width;
+ }
+}
- if( alphaPtr && backPtr) {
-
- alpha = *alphaPtr++;
- data = 0;
- if( dataPtr != 0) {
- if( vc_clut[index + 0] > alpha)
- data |= ((vc_clut[index + 0] - alpha) << 16);
- if( vc_clut[index + 1] > alpha)
- data |= ((vc_clut[index + 1] - alpha) << 8);
- if( vc_clut[index + 2] > alpha)
- data |= ((vc_clut[index + 2] - alpha));
- }
+static void vc_clean_boot_graphics(void)
+{
+ // 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);
+}
- if( save) {
- back = *(dst + col);
- if ( !static_alpha)
- *backPtr++ = back;
- back = (((((back & 0x00ff00ff) * alpha) + 0x00ff00ff) >> 8) & 0x00ff00ff)
- | (((((back & 0x0000ff00) * alpha) + 0x0000ff00) >> 8) & 0x0000ff00);
- if ( static_alpha)
- *backPtr++ = back;
- } else {
- back = *backPtr++;
- if ( !static_alpha) {
- back = (((((back & 0x00ff00ff) * alpha) + 0x00ff00ff) >> 8) & 0x00ff00ff)
- | (((((back & 0x0000ff00) * alpha) + 0x0000ff00) >> 8) & 0x0000ff00);
- }
- }
+/*
+ * Routines to render the lzss image format
+ */
- data += back;
+struct lzss_image_state {
+ uint32_t col;
+ uint32_t row;
+ uint32_t width;
+ uint32_t height;
+ uint32_t bytes_per_row;
+ volatile uint32_t * row_start;
+ const uint8_t* clut;
+};
+typedef struct lzss_image_state lzss_image_state;
- } else
- if( dataPtr != 0) {
- data = (vc_clut[index + 0] << 16)
- | (vc_clut[index + 1] << 8)
- | (vc_clut[index + 2]);
- }
+// returns 0 if OK, 1 if error
+static inline int
+vc_decompress_lzss_next_pixel (int next_data, lzss_image_state* state)
+{
+ uint32_t palette_index = 0;
+ uint32_t pixel_value = 0;
- *(dst + col) = data;
- }
- dst = (volatile unsigned int *) (((int)dst) + vinfo.v_rowbytes);
+ palette_index = next_data * 3;
+
+ pixel_value = ( (uint32_t) state->clut[palette_index + 0] << 16)
+ | ( (uint32_t) state->clut[palette_index + 1] << 8)
+ | ( (uint32_t) state->clut[palette_index + 2]);
+
+ *(state->row_start + state->col) = pixel_value;
+
+ if (++state->col >= state->width) {
+ state->col = 0;
+ if (++state->row >= state->height) {
+ return 1;
+ }
+ state->row_start = (volatile uint32_t *) (((uintptr_t)state->row_start) + state->bytes_per_row);
+ }
+ return 0;
+}
+
+
+/*
+ * Blit an lzss compressed image to the framebuffer
+ * Assumes 32 bit screen (which is everything we ship at the moment)
+ * The function vc_display_lzss_icon was copied from libkern/mkext.c, then modified.
+ */
+
+/*
+ * TODO: Does lzss use too much stack? 4096 plus bytes...
+ * Can probably chop it down by 1/2.
+ */
+
+/**************************************************************
+ LZSS.C -- A Data Compression Program
+***************************************************************
+ 4/6/1989 Haruhiko Okumura
+ Use, distribute, and modify this program freely.
+ Please send me your improved versions.
+ PC-VAN SCIENCE
+ NIFTY-Serve PAF01022
+ CompuServe 74050,1022
+
+**************************************************************/
+
+#define N 4096 /* size of ring buffer - must be power of 2 */
+#define F 18 /* upper limit for match_length */
+#define THRESHOLD 2 /* encode string into position and length
+ if match_length is greater than this */
+
+// returns 0 if OK, 1 if error
+// x and y indicate upper left corner of image location on screen
+int
+vc_display_lzss_icon(uint32_t dst_x, uint32_t dst_y,
+ uint32_t image_width, uint32_t image_height,
+ const uint8_t *compressed_image,
+ uint32_t compressed_size,
+ const uint8_t *clut)
+{
+ uint32_t* image_start;
+ uint32_t bytes_per_pixel = 4;
+ uint32_t bytes_per_row = vinfo.v_rowbytes;
+
+ vc_clean_boot_graphics();
+
+ image_start = (uint32_t *) (vinfo.v_baseaddr + (dst_y * bytes_per_row) + (dst_x * bytes_per_pixel));
+
+ lzss_image_state state = {0, 0, image_width, image_height, bytes_per_row, image_start, clut};
+
+ int rval = 0;
+
+ const uint8_t *src = compressed_image;
+ uint32_t srclen = compressed_size;
+
+ /* ring buffer of size N, with extra F-1 bytes to aid string comparison */
+ uint8_t text_buf[N + F - 1];
+ const uint8_t *srcend = src + srclen;
+ int i, j, k, r, c;
+ unsigned int flags;
+
+ srcend = src + srclen;
+ for (i = 0; i < N - F; i++)
+ text_buf[i] = ' ';
+ r = N - F;
+ flags = 0;
+ for ( ; ; ) {
+ if (((flags >>= 1) & 0x100) == 0) {
+ if (src < srcend) c = *src++; else break;
+ flags = c | 0xFF00; /* uses higher byte cleverly */
+ } /* to count eight */
+ if (flags & 1) {
+ if (src < srcend) c = *src++; else break;
+ rval = vc_decompress_lzss_next_pixel(c, &state);
+ if (rval != 0)
+ return rval;
+ text_buf[r++] = c;
+ r &= (N - 1);
+ } else {
+ if (src < srcend) i = *src++; else break;
+ if (src < srcend) j = *src++; else break;
+ i |= ((j & 0xF0) << 4);
+ j = (j & 0x0F) + THRESHOLD;
+ for (k = 0; k <= j; k++) {
+ c = text_buf[(i + k) & (N - 1)];
+ rval = vc_decompress_lzss_next_pixel(c, &state);
+ if (rval != 0 )
+ return rval;
+ text_buf[r++] = c;
+ r &= (N - 1);
+ }
+ }
}
+ return 0;
+}
+
+void noroot_icon_test(void) {
+ boolean_t o_vc_progress_enable = vc_progress_enable;
+
+ vc_progress_enable = 1;
+
+ PE_display_icon( 0, "noroot");
+
+ vc_progress_enable = o_vc_progress_enable;
}
+
void vc_display_icon( vc_progress_element * desc,
const unsigned char * data )
{
if( vc_progress_enable && vc_clut) {
+ vc_clean_boot_graphics();
+
width = desc->width;
height = desc->height;
x = desc->dx;
x += ((vinfo.v_width - width) / 2);
y += ((vinfo.v_height - height) / 2);
}
- vc_blit_rect( x, y, width, height, data, NULL, NULL, FALSE, TRUE );
+ vc_blit_rect( x, y, 0, width, height, width, 0, data, NULL, kDataIndexed );
}
}
void
vc_progress_initialize( vc_progress_element * desc,
- const unsigned char * data,
+ const unsigned char * data1x,
+ const unsigned char * data2x,
+ const unsigned char * data3x,
const unsigned char * clut )
{
- uint64_t abstime;
+ uint64_t abstime;
- if( (!clut) || (!desc) || (!data))
+ if( (!clut) || (!desc) || (!data1x))
return;
vc_clut = clut;
vc_clut8 = clut;
vc_progress = desc;
- vc_progress_data = data;
+ vc_progress_data[0] = data1x;
+ vc_progress_data[1] = data2x;
+ vc_progress_data[2] = data3x;
if( 2 & vc_progress->flags)
- vc_progress_alpha = vc_progress_data
+ vc_progress_alpha = data1x
+ vc_progress->count * vc_progress->width * vc_progress->height;
else
vc_progress_alpha = NULL;
thread_call_setup(&vc_progress_call, vc_progress_task, NULL);
-
clock_interval_to_absolutetime_interval(vc_progress->time, 1000 * 1000, &abstime);
- vc_progress_interval = abstime;
+ vc_progress_interval = (uint32_t)abstime;
+
+ 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;
- simple_lock_init(&vc_progress_lock, 0);
}
-static void
-vc_progress_set( boolean_t enable, uint32_t delay )
+void
+vc_progress_set(boolean_t enable, uint32_t vc_delay)
{
spl_t s;
- void *saveBuf = 0;
+ void *saveBuf = NULL;
vm_size_t saveLen = 0;
unsigned int count;
unsigned int index;
unsigned int pdata32;
unsigned int * buf32;
- if( !vc_progress)
+
+ if (kBootArgsFlagBlack & ((boot_args *) PE_state.bootArgs)->flags) return;
+
+ if (1 & vc_progress_withmeter)
+ {
+ if (enable) internal_enable_progressmeter(kProgressMeterKernel);
+
+ s = splhigh();
+ simple_lock(&vc_progress_lock);
+
+ if( vc_progress_enable != enable) {
+ vc_progress_enable = enable;
+ if( enable)
+ {
+ vc_progressmeter_count = 0;
+ clock_interval_to_deadline(vc_delay,
+ 1000 * 1000 * 1000 /*second scale*/,
+ &vc_progressmeter_deadline);
+ thread_call_enter_delayed(&vc_progressmeter_call, vc_progressmeter_deadline);
+ }
+ else thread_call_cancel(&vc_progressmeter_call);
+ }
+
+ simple_unlock(&vc_progress_lock);
+ splx(s);
+
+ if (!enable) internal_enable_progressmeter(kProgressMeterOff);
return;
+ }
+
+
+ if(!vc_progress) return;
if( enable) {
- saveLen = vc_progress->width * vc_progress->height * vinfo.v_depth / 8;
+ saveLen = (vc_progress->width * vc_uiscale) * (vc_progress->height * vc_uiscale) * vinfo.v_depth / 8;
saveBuf = kalloc( saveLen );
switch( vinfo.v_depth) {
case 16 :
buf16 = (unsigned short *) saveBuf;
- pdata16 = ((vc_clut[0x01 * 3 + 0] & 0xf8) << 7)
- | ((vc_clut[0x01 * 3 + 0] & 0xf8) << 2)
- | ((vc_clut[0x01 * 3 + 0] & 0xf8) >> 3);
+ pdata16 = ((vc_clut[0x01 * 3 + 0] & CLUT_MASK_R) CLUT_SHIFT_R)
+ | ((vc_clut[0x01 * 3 + 0] & CLUT_MASK_G) CLUT_SHIFT_G)
+ | ((vc_clut[0x01 * 3 + 0] & CLUT_MASK_B) CLUT_SHIFT_B);
for( count = 0; count < saveLen / 2; count++)
buf16[count] = pdata16;
break;
vc_needsave = TRUE;
vc_saveunder = saveBuf;
vc_saveunder_len = saveLen;
- saveBuf = 0;
- saveLen = 0;
-
- clock_interval_to_deadline(delay, 1000 * 1000 * 1000 /*second scale*/, &vc_progress_deadline);
+ saveBuf = NULL;
+ saveLen = 0;
+ vc_progress_count = 0;
+ vc_progress_angle = 0;
+
+ clock_interval_to_deadline(vc_delay,
+ 1000 * 1000 * 1000 /*second scale*/,
+ &vc_progress_deadline);
thread_call_enter_delayed(&vc_progress_call, vc_progress_deadline);
} else {
if( vc_saveunder) {
saveBuf = vc_saveunder;
saveLen = vc_saveunder_len;
- vc_saveunder = 0;
+ vc_saveunder = NULL;
vc_saveunder_len = 0;
}
kfree( saveBuf, saveLen );
}
-static void vc_progress_task( void * arg0, void * arg )
+
+static uint32_t vc_progressmeter_range(uint32_t pos)
{
- spl_t s;
- int count = (int) arg;
- int x, y, width, height;
- const unsigned char * data;
+ 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)
+{
+ spl_t s;
+ uint64_t interval;
s = splhigh();
simple_lock(&vc_progress_lock);
+ if (vc_progressmeter_enable)
+ {
+ uint32_t pos = (vc_progressmeter_count >> 13);
+ 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_count += incr[(pos * 8) / kProgressMeterEnd];
+
+ interval = vc_progressmeter_interval;
+ interval = ((interval * 256) / vc_progressmeter_diskspeed);
+
+ clock_deadline_for_periodic_event(interval, mach_absolute_time(), &vc_progressmeter_deadline);
+ thread_call_enter_delayed(&vc_progressmeter_call, vc_progressmeter_deadline);
+ }
+ }
+ simple_unlock(&vc_progress_lock);
+ splx(s);
+}
- if( vc_progress_enable) {
+void vc_progress_setdiskspeed(uint32_t speed)
+{
+ vc_progressmeter_diskspeed = speed;
+}
- count++;
- if( count >= vc_progress->count)
- count = 0;
- width = vc_progress->width;
- height = vc_progress->height;
- x = vc_progress->dx;
- y = vc_progress->dy;
- data = vc_progress_data;
- data += count * width * height;
- if( 1 & vc_progress->flags) {
- x += ((vinfo.v_width - width) / 2);
- y += ((vinfo.v_height - height) / 2);
+static void
+vc_progress_task(__unused void *arg0, __unused void *arg)
+{
+ 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) do {
+
+ vc_progress_count++;
+ if( vc_progress_count >= vc_progress->count) {
+ vc_progress_count = 0;
+ vc_progress_angle++;
+ }
+
+ width = (vc_progress->width * vc_uiscale);
+ height = (vc_progress->height * vc_uiscale);
+ 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);
+ }
}
- vc_blit_rect( x, y, width, height,
- NULL, data, vc_saveunder,
- vc_needsave, (0 == (4 & vc_progress->flags)) );
- vc_needsave = FALSE;
- clock_deadline_for_periodic_event(vc_progress_interval, mach_absolute_time(), &vc_progress_deadline);
- thread_call_enter1_delayed(&vc_progress_call, (void *)count, 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);
}
* -------------------------------------------
*/
-#ifdef __i386__
-#include <console/i386/text_console.h>
-#endif /* __i386__ */
+#if defined (__i386__) || defined (__x86_64__)
+#include <pexpert/i386/boot.h>
+#endif
static boolean_t gc_acquired = FALSE;
static boolean_t gc_graphics_boot = FALSE;
+static boolean_t gc_desire_text = FALSE;
+static boolean_t gc_paused_progress;
+
+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 )
+{
+ spl_t s;
-static unsigned int lastVideoPhys = 0;
-static unsigned int lastVideoVirt = 0;
-static unsigned int lastVideoSize = 0;
+ s = splhigh( );
+ VCPUTC_LOCK_LOCK( );
+
+ disableConsoleOutput = (pause && !console_is_serial());
+ gc_enabled = (!pause && !graphics_now);
+
+ VCPUTC_LOCK_UNLOCK( );
+
+ simple_lock(&vc_progress_lock);
+
+ if (pause)
+ {
+ gc_paused_progress = vc_progress_enable;
+ vc_progress_enable = FALSE;
+ }
+ else vc_progress_enable = gc_paused_progress;
+
+ if (vc_progress_enable)
+ {
+ if (1 & vc_progress_withmeter) thread_call_enter_delayed(&vc_progressmeter_call, vc_progressmeter_deadline);
+ else
+ thread_call_enter_delayed(&vc_progress_call, vc_progress_deadline);
+ }
+
+ simple_unlock(&vc_progress_lock);
+ splx(s);
+}
+
+static void
+vc_initialize(__unused struct vc_info * vinfo_p)
+{
+
+ vinfo.v_rows = vinfo.v_height / ISO_CHAR_HEIGHT;
+ vinfo.v_columns = vinfo.v_width / ISO_CHAR_WIDTH;
+ vinfo.v_rowscanbytes = ((vinfo.v_depth + 7) / 8) * vinfo.v_width;
+ vc_uiscale = vinfo.v_scale;
+ if (vc_uiscale > kMaxProgressData) vc_uiscale = kMaxProgressData;
+ else if (!vc_uiscale) vc_uiscale = 1;
+}
void
-initialize_screen(Boot_Video * boot_vinfo, unsigned int op)
+initialize_screen(PE_Video * boot_vinfo, unsigned int op)
{
- unsigned int fbsize;
- unsigned int newVideoVirt;
- ppnum_t fbppage;
+ unsigned int newMapSize = 0;
+ vm_offset_t newVideoVirt = 0;
+ boolean_t graphics_now;
+ uint32_t delay;
if ( boot_vinfo )
{
-// bcopy((const void *)boot_vinfo, (void *)&boot_video_info, sizeof(boot_video_info));
+ 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
*/
+ 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_type = 0;
+#endif
+ unsigned int scale = (unsigned int)boot_vinfo->v_scale;
+ if (scale == kPEScaleFactor1x )
+ new_vinfo.v_scale = kPEScaleFactor1x;
+ else if (scale == kPEScaleFactor2x)
+ 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;
- vinfo.v_name[0] = 0;
- vinfo.v_width = boot_vinfo->v_width;
- vinfo.v_height = boot_vinfo->v_height;
- vinfo.v_depth = boot_vinfo->v_depth;
- vinfo.v_rowbytes = boot_vinfo->v_rowBytes;
- vinfo.v_physaddr = boot_vinfo->v_baseAddr; /* Get the physical address */
-
- kprintf("initialize_screen: b=%08X, w=%08X, h=%08X, r=%08X\n", /* (BRINGUP) */
- vinfo.v_physaddr, vinfo.v_width, vinfo.v_height, vinfo.v_rowbytes); /* (BRINGUP) */
-
- if (!vinfo.v_physaddr) /* Check to see if we have a framebuffer */
+ /*
+ * 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 (!newVideoVirt && !new_vinfo.v_physaddr) /* Check to see if we have a framebuffer */
{
kprintf("initialize_screen: No video - forcing serial mode\n"); /* (BRINGUP) */
- vinfo.v_depth = 0; /* vc routines are nop */
+ new_vinfo.v_depth = 0; /* vc routines are nop */
(void)switch_to_serial_console(); /* Switch into serial mode */
gc_graphics_boot = FALSE; /* Say we are not in graphics mode */
disableConsoleOutput = FALSE; /* Allow printfs to happen */
}
else
{
- /*
- * Note that for the first time only, boot_vinfo->v_baseAddr is physical.
- */
-
- if (kernel_map != VM_MAP_NULL) /* If VM is up, we are given a virtual address */
- {
- 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", boot_vinfo->v_baseAddr);
- }
- vinfo.v_physaddr = (fbppage << 12) | (boot_vinfo->v_baseAddr & PAGE_MASK); /* Get the physical address */
- }
-
-#ifdef __i386__
- vinfo.v_type = boot_vinfo->v_display;
-#else
- vinfo.v_type = 0;
-#endif
-
- fbsize = round_page_32(vinfo.v_height * vinfo.v_rowbytes); /* Remember size */
-
- if ((lastVideoPhys != vinfo.v_physaddr) || (fbsize > lastVideoSize)) /* Did framebuffer change location or get bigger? */
+ if (makeMapping)
{
- newVideoVirt = io_map_spec((vm_offset_t)vinfo.v_physaddr, fbsize); /* Allocate address space for framebuffer */
-
- if (lastVideoVirt) /* Was the framebuffer mapped before? */
- {
- pmap_remove(kernel_pmap, trunc_page_64(lastVideoVirt),
- round_page_64(lastVideoVirt + lastVideoSize)); /* Toss mappings */
-
- if(lastVideoVirt <= vm_last_addr) /* Was this not a special pre-VM mapping? */
- {
- kmem_free(kernel_map, lastVideoVirt, lastVideoSize); /* Toss kernel addresses */
- }
- }
-
- lastVideoPhys = vinfo.v_physaddr; /* Remember the framebuffer address */
- lastVideoSize = fbsize; /* Remember the size */
- lastVideoVirt = newVideoVirt; /* Remember the virtual framebuffer address */
- }
+ unsigned int flags = VM_WIMG_IO;
+ 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 */
}
- vinfo.v_baseaddr = lastVideoVirt; /* 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)
+ new_vinfo.v_baseaddr |= (VM_MIN_KERNEL_ADDRESS & ~LOW_4GB_MASK);
+#endif
-#ifdef __i386__
- if ( (vinfo.v_type == TEXT_MODE) )
+ /* Update the vinfo structure atomically with respect to the vc_progress task if running */
+ if (vc_progress)
{
- // Text mode setup by the booter.
-
- gc_ops.initialize = tc_initialize;
- gc_ops.enable = tc_enable;
- gc_ops.paint_char = tc_paint_char;
- gc_ops.clear_screen = tc_clear_screen;
- gc_ops.scroll_down = tc_scroll_down;
- gc_ops.scroll_up = tc_scroll_up;
- gc_ops.hide_cursor = tc_hide_cursor;
- gc_ops.show_cursor = tc_show_cursor;
- gc_ops.update_color = tc_update_color;
+ simple_lock(&vc_progress_lock);
+ vinfo = new_vinfo;
+ simple_unlock(&vc_progress_lock);
}
else
-#endif /* __i386__ */
{
+ vinfo = new_vinfo;
+ }
+
+ // If we changed the virtual address, remove the old mapping
+ if (newVideoVirt != 0)
+ {
+ if (lastVideoVirt && lastVideoMapSize) /* Was the framebuffer mapped before? */
+ {
+ /* XXX why only !4K? */
+ if (!TEST_PAGE_SIZE_4K && lastVideoMapSize)
+ {
+ pmap_remove(kernel_pmap, trunc_page_64(lastVideoVirt),
+ round_page_64(lastVideoVirt + lastVideoMapSize)); /* Toss mappings */
+ }
+ /* Was this not a special pre-VM mapping? */
+ if (lastVideoMapKmap)
+ {
+ kmem_free(kernel_map, lastVideoVirt, lastVideoMapSize); /* Toss kernel addresses */
+ }
+ }
+ lastVideoMapKmap = (NULL != kernel_map); /* Remember how mapped */
+ lastVideoMapSize = newMapSize; /* Remember the size */
+ lastVideoVirt = newVideoVirt; /* Remember the virtual framebuffer address */
+ }
+
+ if (kPEBaseAddressChange != op)
+ {
// Graphics mode setup by the booter.
gc_ops.initialize = vc_initialize;
gc_ops.hide_cursor = vc_reverse_cursor;
gc_ops.show_cursor = vc_reverse_cursor;
gc_ops.update_color = vc_update_color;
+ gc_initialize(&vinfo);
}
-
- gc_initialize(&vinfo);
-
-#ifdef GRATEFULDEBUGGER
- GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re-initialize GratefulDeb */
-#endif /* GRATEFULDEBUGGER */
}
+ graphics_now = gc_graphics_boot && !gc_desire_text;
switch ( op )
{
case kPEGraphicsMode:
- panicDialogDesired = TRUE;
gc_graphics_boot = TRUE;
+ gc_desire_text = FALSE;
break;
case kPETextMode:
- panicDialogDesired = FALSE;
+ disable_debug_output = FALSE;
gc_graphics_boot = FALSE;
break;
case kPEAcquireScreen:
if ( gc_acquired ) break;
- vc_progress_set( gc_graphics_boot, kProgressAcquireDelay );
- gc_enable( !gc_graphics_boot );
+ 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;
+ break;
+
+ case kPEDisableScreen:
+ if (gc_acquired)
+ {
+ gc_pause( TRUE, graphics_now );
+ }
break;
case kPEEnableScreen:
- /* deprecated */
+ if (gc_acquired)
+ {
+ gc_pause( FALSE, graphics_now );
+ }
break;
case kPETextScreen:
- panicDialogDesired = FALSE;
- if ( gc_acquired == FALSE ) break;
+ if ( console_is_serial() ) break;
+
+ disable_debug_output = FALSE;
+ if ( gc_acquired == FALSE )
+ {
+ gc_desire_text = TRUE;
+ break;
+ }
if ( gc_graphics_boot == FALSE ) break;
vc_progress_set( FALSE, 0 );
+ vc_enable_progressmeter( FALSE );
gc_enable( TRUE );
break;
- case kPEDisableScreen:
- /* deprecated */
- /* skip break */
-
case kPEReleaseScreen:
gc_acquired = FALSE;
+ gc_desire_text = FALSE;
gc_enable( FALSE );
- vc_progress_set( FALSE, 0 );
+ if ( gc_graphics_boot == FALSE ) break;
+ vc_progress_set( FALSE, 0 );
+ vc_acquire_delay = kProgressReacquireDelay;
+ vc_progress_white = TRUE;
+ vc_enable_progressmeter(FALSE);
+ vc_progress_withmeter &= ~1;
vc_clut8 = NULL;
-#ifdef GRATEFULDEBUGGER
- GratefulDebInit(0); /* Stop grateful debugger */
-#endif /* GRATEFULDEBUGGER */
break;
- }
-#ifdef GRATEFULDEBUGGER
- if ( boot_vinfo ) GratefulDebInit((bootBumbleC *)boot_vinfo); /* Re initialize GratefulDeb */
-#endif /* GRATEFULDEBUGGER */
-}
-void
-refresh_screen(void)
-{
- if ( gc_enabled )
- {
- gc_refresh_screen();
- gc_show_cursor(gc_x, gc_y);
+
+ case kPERefreshBootGraphics:
+ {
+ spl_t s;
+ boolean_t save;
+
+ if (kBootArgsFlagBlack & ((boot_args *) PE_state.bootArgs)->flags) break;
+
+ save = vc_progress_white;
+ vc_progress_white = (0 != (kBootArgsFlagBlackBg & ((boot_args *) PE_state.bootArgs)->flags));
+
+ internal_enable_progressmeter(kProgressMeterKernel);
+
+ s = splhigh();
+ simple_lock(&vc_progress_lock);
+
+ vc_progressmeter_drawn = 0;
+ 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 vcattach(void); /* XXX gcc 4 warning cleanup */
+
void
vcattach(void)
{
- extern struct { long msg_magic; long msg_bufx; long msg_bufr; char msg_bufc[]; } * msgbufp;
-
vm_initialized = TRUE;
+ const boot_args * bootargs = (typeof(bootargs)) PE_state.bootArgs;
+
+ vc_progress_white = (0 != ((kBootArgsFlagBlackBg | kBootArgsFlagLoginUI)
+ & 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 )
{
- unsigned int index;
+ long index;
if ( gc_acquired )
{
- initialize_screen( 0, kPEReleaseScreen );
+ initialize_screen(NULL, kPEReleaseScreen);
}
- initialize_screen( 0, kPEAcquireScreen );
+ initialize_screen(NULL, kPEAcquireScreen);
for ( index = 0 ; index < msgbufp->msg_bufx ; index++ )
{
+ if (msgbufp->msg_bufc[index] == '\0') {
+ continue;
+ }
+
vcputc( 0, 0, msgbufp->msg_bufc[index] );
if ( msgbufp->msg_bufc[index] == '\n' )
}
}
}
+
+
+// redraw progress meter between pixels x1, x2, position at x3
+static void
+vc_draw_progress_meter(unsigned int flags, int x1, int x2, int x3)
+{
+ const unsigned char * data;
+ int x, w;
+ int ox, oy;
+ int endCapPos;
+ int onoff;
+ // 1 rounded fill, 0 square end
+ int style = (0 == (2 & vc_progress_withmeter));
+
+ ox = ((vinfo.v_width - (kProgressBarWidth * vc_uiscale)) / 2);
+ oy = vinfo.v_height - (vinfo.v_height / 3) - ((kProgressBarHeight * vc_uiscale) / 2);
+
+ if (kDataBack == flags)
+ {
+ // restore back bits
+ vc_blit_rect(ox + x1, oy, x1,
+ x2, (kProgressBarHeight * vc_uiscale), 0, (kProgressBarWidth * vc_uiscale),
+ NULL, vc_progressmeter_backbuffer, flags);
+ return;
+ }
+
+ for (x = x1; x < x2; x += w)
+ {
+ onoff = (x < x3);
+ endCapPos = ((style && onoff) ? x3 : (kProgressBarWidth * vc_uiscale));
+ if (x < (kProgressBarCapWidth * vc_uiscale))
+ {
+ if (x2 < (kProgressBarCapWidth * vc_uiscale))
+ w = x2 - x;
+ else
+ w = (kProgressBarCapWidth * vc_uiscale) - x;
+ data = progressmeter_leftcap[vc_uiscale >= 2][onoff];
+ data += x;
+ vc_blit_rect(ox + x, oy, x, w,
+ (kProgressBarHeight * vc_uiscale),
+ (kProgressBarCapWidth * vc_uiscale),
+ (kProgressBarWidth * vc_uiscale),
+ data, vc_progressmeter_backbuffer, flags);
+ }
+ else if (x < (endCapPos - (kProgressBarCapWidth * vc_uiscale)))
+ {
+ if (x2 < (endCapPos - (kProgressBarCapWidth * vc_uiscale)))
+ w = x2 - x;
+ else
+ w = (endCapPos - (kProgressBarCapWidth * vc_uiscale)) - x;
+ data = progressmeter_middle[vc_uiscale >= 2][onoff];
+ vc_blit_rect(ox + x, oy, x, w,
+ (kProgressBarHeight * vc_uiscale),
+ 1,
+ (kProgressBarWidth * vc_uiscale),
+ data, vc_progressmeter_backbuffer, flags);
+ }
+ else
+ {
+ w = endCapPos - x;
+ data = progressmeter_rightcap[vc_uiscale >= 2][onoff];
+ data += x - (endCapPos - (kProgressBarCapWidth * vc_uiscale));
+ vc_blit_rect(ox + x, oy, x, w,
+ (kProgressBarHeight * vc_uiscale),
+ (kProgressBarCapWidth * vc_uiscale),
+ (kProgressBarWidth * vc_uiscale),
+ data, vc_progressmeter_backbuffer, flags);
+ }
+ }
+}
+
+extern void IORecordProgressBackbuffer(void * buffer, size_t size, uint32_t theme);
+
+static void
+internal_enable_progressmeter(int new_value)
+{
+ spl_t s;
+ void * new_buffer;
+ boolean_t stashBackbuffer;
+
+ stashBackbuffer = FALSE;
+ new_buffer = NULL;
+ if (new_value)
+ {
+ new_buffer = kalloc((kProgressBarWidth * vc_uiscale)
+ * (kProgressBarHeight * vc_uiscale) * sizeof(int));
+ }
+
+ s = splhigh();
+ simple_lock(&vc_progress_lock);
+
+ if (kProgressMeterUser == new_value)
+ {
+ if (gc_enabled || !gc_acquired || !gc_graphics_boot
+ || (kProgressMeterKernel == vc_progressmeter_enable)) new_value = vc_progressmeter_enable;
+ }
+
+ if (new_value != vc_progressmeter_enable)
+ {
+ if (new_value)
+ {
+ if (kProgressMeterOff == vc_progressmeter_enable)
+ {
+ vc_progressmeter_backbuffer = new_buffer;
+ vc_draw_progress_meter(kDataAlpha | kSave, 0, (kProgressBarWidth * vc_uiscale), 0);
+ new_buffer = NULL;
+ vc_progressmeter_drawn = 0;
+ }
+ vc_progressmeter_enable = new_value;
+ }
+ else if (vc_progressmeter_backbuffer)
+ {
+ if (kProgressMeterUser == vc_progressmeter_enable)
+ {
+ vc_draw_progress_meter(kDataBack, 0, (kProgressBarWidth * vc_uiscale), vc_progressmeter_drawn);
+ }
+ else stashBackbuffer = TRUE;
+ new_buffer = vc_progressmeter_backbuffer;
+ vc_progressmeter_backbuffer = NULL;
+ vc_progressmeter_enable = FALSE;
+ }
+ }
+
+ simple_unlock(&vc_progress_lock);
+ splx(s);
+
+ if (new_buffer)
+ {
+ if (stashBackbuffer) IORecordProgressBackbuffer(new_buffer,
+ (kProgressBarWidth * vc_uiscale)
+ * (kProgressBarHeight * vc_uiscale)
+ * sizeof(int),
+ vc_progress_white);
+ kfree(new_buffer, (kProgressBarWidth * vc_uiscale)
+ * (kProgressBarHeight * vc_uiscale) * sizeof(int));
+ }
+}
+
+static void
+internal_set_progressmeter(int new_value)
+{
+ int x1, x3;
+ int capRedraw;
+ // 1 rounded fill, 0 square end
+ int style = (0 == (2 & vc_progress_withmeter));
+
+ if ((new_value < 0) || (new_value > kProgressMeterMax)) return;
+
+ if (vc_progressmeter_enable)
+ {
+ vc_progressmeter_value = new_value;
+
+ capRedraw = (style ? (kProgressBarCapWidth * vc_uiscale) : 0);
+ x3 = (((kProgressBarWidth * vc_uiscale) - 2 * capRedraw) * vc_progressmeter_value) / kProgressMeterMax;
+ x3 += (2 * capRedraw);
+
+ if (x3 > vc_progressmeter_drawn)
+ {
+ x1 = capRedraw;
+ if (x1 > vc_progressmeter_drawn) x1 = vc_progressmeter_drawn;
+ vc_draw_progress_meter(kDataAlpha, vc_progressmeter_drawn - x1, x3, x3);
+ }
+ else
+ {
+ vc_draw_progress_meter(kDataAlpha, x3 - capRedraw, vc_progressmeter_drawn, x3);
+ }
+ vc_progressmeter_drawn = x3;
+ }
+}
+
+void
+vc_enable_progressmeter(int new_value)
+{
+ if (kProgressMeterKernel == vc_progressmeter_enable)
+ {
+ vc_progressmeter_hold = new_value;
+ }
+ else
+ {
+ internal_enable_progressmeter(new_value ? kProgressMeterUser : kProgressMeterOff);
+ }
+}
+
+void
+vc_set_progressmeter(int new_value)
+{
+ spl_t s;
+
+ s = splhigh();
+ simple_lock(&vc_progress_lock);
+
+ if (vc_progressmeter_enable && (kProgressMeterKernel != vc_progressmeter_enable))
+ {
+ internal_set_progressmeter((new_value * kProgressMeterMax) / 100);
+ }
+
+ simple_unlock(&vc_progress_lock);
+ splx(s);
+}
+
+
+
+