2 * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * @OSF_FREE_COPYRIGHT@
33 * @APPLE_FREE_COPYRIGHT@
36 * NetBSD: ite.c,v 1.16 1995/07/17 01:24:34 briggs Exp
38 * Copyright (c) 1988 University of Utah.
39 * Copyright (c) 1990, 1993
40 * The Regents of the University of California. All rights reserved.
42 * This code is derived from software contributed to Berkeley by
43 * the Systems Programming Group of the University of Utah Computer
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
49 * 1. Redistributions of source code must retain the above copyright
50 * notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 * notice, this list of conditions and the following disclaimer in the
53 * documentation and/or other materials provided with the distribution.
54 * 3. All advertising materials mentioning features or use of this software
55 * must display the following acknowledgement:
56 * This product includes software developed by the University of
57 * California, Berkeley and its contributors.
58 * 4. Neither the name of the University nor the names of its contributors
59 * may be used to endorse or promote products derived from this software
60 * without specific prior written permission.
62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74 * from: Utah $Hdr: ite.c 1.28 92/12/20$
76 * @(#)ite.c 8.2 (Berkeley) 1/12/94
82 * The ite module handles the system console; that is, stuff printed
83 * by the kernel and by user programs while "desktop" and X aren't
84 * running. Some (very small) parts are based on hp300's 4.4 ite.c,
85 * hence the above copyright.
87 * -- Brad and Lawrence, June 26th, 1994
93 #include <console/video_console.h>
94 #include <console/serial_protos.h>
96 #include <kern/kern_types.h>
97 #include <kern/kalloc.h>
98 #include <kern/debug.h>
99 #include <kern/lock.h>
100 #include <kern/spl.h>
101 #include <kern/thread_call.h>
104 #include <vm/vm_kern.h>
105 #include <machine/io_map_entries.h>
106 #include <machine/machine_cpu.h>
108 #include <pexpert/pexpert.h>
109 #include <sys/kdebug.h>
111 #include "iso_font.c"
113 #include "progress_meter_data.c"
116 #include "sys/msgbuf.h"
119 * Generic Console (Front-End)
120 * ---------------------------
123 struct vc_info vinfo
;
124 /* if panicDialogDesired is true then we use the panic dialog when its */
125 /* allowed otherwise we won't use the panic dialog even if it is allowed */
126 boolean_t panicDialogDesired
;
129 extern int disableConsoleOutput
;
130 static boolean_t gc_enabled
= FALSE
;
131 static boolean_t gc_initialized
= FALSE
;
132 static boolean_t vm_initialized
= FALSE
;
135 void (*initialize
)(struct vc_info
* info
);
136 void (*enable
)(boolean_t enable
);
137 void (*paint_char
)(unsigned int xx
, unsigned int yy
, unsigned char ch
,
138 int attrs
, unsigned char ch_previous
,
140 void (*clear_screen
)(unsigned int xx
, unsigned int yy
, unsigned int top
,
141 unsigned int bottom
, int which
);
142 void (*scroll_down
)(int num
, unsigned int top
, unsigned int bottom
);
143 void (*scroll_up
)(int num
, unsigned int top
, unsigned int bottom
);
144 void (*hide_cursor
)(unsigned int xx
, unsigned int yy
);
145 void (*show_cursor
)(unsigned int xx
, unsigned int yy
);
146 void (*update_color
)(int color
, boolean_t fore
);
149 static unsigned char *gc_buffer_attributes
;
150 static unsigned char *gc_buffer_characters
;
151 static unsigned char *gc_buffer_colorcodes
;
152 static uint32_t gc_buffer_columns
;
153 static uint32_t gc_buffer_rows
;
154 static uint32_t gc_buffer_size
;
157 decl_simple_lock_data(static, vcputc_lock
);
159 #define VCPUTC_LOCK_INIT() \
161 simple_lock_init(&vcputc_lock, 0); \
164 #define VCPUTC_LOCK_LOCK() \
166 boolean_t istate = ml_get_interrupts_enabled(); \
167 while (!simple_lock_try(&vcputc_lock)) \
170 handle_pending_TLB_flushes(); \
175 #define VCPUTC_LOCK_UNLOCK() \
177 simple_unlock(&vcputc_lock); \
180 static hw_lock_data_t vcputc_lock
;
182 #define VCPUTC_LOCK_INIT() \
184 hw_lock_init(&vcputc_lock); \
187 #define VCPUTC_LOCK_LOCK() \
189 if (!hw_lock_to(&vcputc_lock, LockTimeOut*10)) \
191 panic("VCPUTC_LOCK_LOCK"); \
195 #define VCPUTC_LOCK_UNLOCK() \
197 hw_lock_unlock(&vcputc_lock); \
203 # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
205 # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
206 # Background color codes:
207 # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
213 #define ATTR_REVERSE 4
215 #define COLOR_BACKGROUND 0
216 #define COLOR_FOREGROUND 7
218 #define COLOR_CODE_GET(code, fore) (((code) & ((fore) ? 0xF0 : 0x0F)) >> ((fore) ? 4 : 0))
219 #define COLOR_CODE_SET(code, color, fore) (((code) & ((fore) ? 0x0F : 0xF0)) | ((color) << ((fore) ? 4 : 0)))
221 static unsigned char gc_color_code
;
225 static unsigned int gc_x
, gc_y
, gc_savex
, gc_savey
;
226 static unsigned int gc_par
[MAXPARS
], gc_numpars
, gc_hanging_cursor
, gc_attr
, gc_saveattr
;
228 /* VT100 tab stops & scroll region */
229 static char gc_tab_stops
[255];
230 static unsigned int gc_scrreg_top
, gc_scrreg_bottom
;
232 #ifdef CONFIG_VC_PROGRESS_WHITE
233 enum { kProgressAcquireDelay
= 0 /* secs */ };
235 enum { kProgressAcquireDelay
= 5 /* secs */ };
239 ESnormal
, /* Nothing yet */
241 ESsquare
, /* Got ESC [ */
242 ESgetpars
, /* About to get or getting the parameters */
243 ESgotpars
, /* Finished getting the parameters */
244 ESfunckey
, /* Function key */
245 EShash
, /* DEC-specific stuff (screen align, etc.) */
246 ESsetG0
, /* Specify the G0 character set */
247 ESsetG1
, /* Specify the G1 character set */
250 ESignore
/* Ignore this sequence */
251 } gc_vt100state
= ESnormal
;
253 static int gc_wrap_mode
= 1, gc_relative_origin
= 0;
254 static int gc_charset_select
= 0, gc_save_charset_s
= 0;
255 static int gc_charset
[2] = { 0, 0 };
256 static int gc_charset_save
[2] = { 0, 0 };
258 static void gc_clear_line(unsigned int xx
, unsigned int yy
, int which
);
259 static void gc_clear_screen(unsigned int xx
, unsigned int yy
, int top
,
260 unsigned int bottom
, int which
);
261 static void gc_enable(boolean_t enable
);
262 static void gc_hide_cursor(unsigned int xx
, unsigned int yy
);
263 static void gc_initialize(struct vc_info
* info
);
264 static void gc_paint_char(unsigned int xx
, unsigned int yy
, unsigned char ch
,
266 static void gc_putchar(char ch
);
267 static void gc_putc_askcmd(unsigned char ch
);
268 static void gc_putc_charsetcmd(int charset
, unsigned char ch
);
269 static void gc_putc_charsizecmd(unsigned char ch
);
270 static void gc_putc_esc(unsigned char ch
);
271 static void gc_putc_getpars(unsigned char ch
);
272 static void gc_putc_gotpars(unsigned char ch
);
273 static void gc_putc_normal(unsigned char ch
);
274 static void gc_putc_square(unsigned char ch
);
275 static void gc_reset_screen(void);
276 static void gc_reset_tabs(void);
277 static void gc_reset_vt100(void);
278 static void gc_scroll_down(int num
, unsigned int top
, unsigned int bottom
);
279 static void gc_scroll_up(int num
, unsigned int top
, unsigned int bottom
);
280 static void gc_show_cursor(unsigned int xx
, unsigned int yy
);
281 static void gc_update_color(int color
, boolean_t fore
);
284 gc_clear_line(unsigned int xx
, unsigned int yy
, int which
)
286 unsigned int start
, end
, i
;
289 * This routine runs extremely slowly. I don't think it's
290 * used all that often, except for To end of line. I'll go
291 * back and speed this up when I speed up the whole vc
296 case 0: /* To end of line */
298 end
= vinfo
.v_columns
-1;
300 case 1: /* To start of line */
304 case 2: /* Whole line */
306 end
= vinfo
.v_columns
-1;
312 for (i
= start
; i
<= end
; i
++) {
313 gc_paint_char(i
, yy
, ' ', ATTR_NONE
);
318 gc_clear_screen(unsigned int xx
, unsigned int yy
, int top
, unsigned int bottom
,
321 if (!gc_buffer_size
) return;
323 if ( xx
< gc_buffer_columns
&& yy
< gc_buffer_rows
&& bottom
<= gc_buffer_rows
)
328 case 0: /* To end of screen */
329 start
= (yy
* gc_buffer_columns
) + xx
;
330 end
= (bottom
* gc_buffer_columns
) - 1;
332 case 1: /* To start of screen */
333 start
= (top
* gc_buffer_columns
);
334 end
= (yy
* gc_buffer_columns
) + xx
;
336 case 2: /* Whole screen */
337 start
= (top
* gc_buffer_columns
);
338 end
= (bottom
* gc_buffer_columns
) - 1;
346 memset(gc_buffer_attributes
+ start
, ATTR_NONE
, end
- start
+ 1);
347 memset(gc_buffer_characters
+ start
, ' ', end
- start
+ 1);
348 memset(gc_buffer_colorcodes
+ start
, gc_color_code
, end
- start
+ 1);
351 gc_ops
.clear_screen(xx
, yy
, top
, bottom
, which
);
355 gc_enable( boolean_t enable
)
357 unsigned char *buffer_attributes
= NULL
;
358 unsigned char *buffer_characters
= NULL
;
359 unsigned char *buffer_colorcodes
= NULL
;
360 uint32_t buffer_columns
= 0;
361 uint32_t buffer_rows
= 0;
362 uint32_t buffer_size
= 0;
365 if ( enable
== FALSE
)
367 // only disable console output if it goes to the graphics console
368 if ( console_is_serial() == FALSE
)
369 disableConsoleOutput
= TRUE
;
371 gc_ops
.enable(FALSE
);
377 if ( gc_buffer_size
)
379 buffer_attributes
= gc_buffer_attributes
;
380 buffer_characters
= gc_buffer_characters
;
381 buffer_colorcodes
= gc_buffer_colorcodes
;
382 buffer_size
= gc_buffer_size
;
384 gc_buffer_attributes
= NULL
;
385 gc_buffer_characters
= NULL
;
386 gc_buffer_colorcodes
= NULL
;
387 gc_buffer_columns
= 0;
391 VCPUTC_LOCK_UNLOCK( );
394 kfree( buffer_attributes
, buffer_size
);
395 kfree( buffer_characters
, buffer_size
);
396 kfree( buffer_colorcodes
, buffer_size
);
400 VCPUTC_LOCK_UNLOCK( );
406 if ( vm_initialized
)
408 buffer_columns
= vinfo
.v_columns
;
409 buffer_rows
= vinfo
.v_rows
;
410 buffer_size
= buffer_columns
* buffer_rows
;
414 buffer_attributes
= (unsigned char *) kalloc( buffer_size
);
415 buffer_characters
= (unsigned char *) kalloc( buffer_size
);
416 buffer_colorcodes
= (unsigned char *) kalloc( buffer_size
);
418 if ( buffer_attributes
== NULL
||
419 buffer_characters
== NULL
||
420 buffer_colorcodes
== NULL
)
422 if ( buffer_attributes
) kfree( buffer_attributes
, buffer_size
);
423 if ( buffer_characters
) kfree( buffer_characters
, buffer_size
);
424 if ( buffer_colorcodes
) kfree( buffer_colorcodes
, buffer_size
);
432 memset( buffer_attributes
, ATTR_NONE
, buffer_size
);
433 memset( buffer_characters
, ' ', buffer_size
);
434 memset( buffer_colorcodes
, COLOR_CODE_SET( 0, COLOR_FOREGROUND
, TRUE
), buffer_size
);
442 gc_buffer_attributes
= buffer_attributes
;
443 gc_buffer_characters
= buffer_characters
;
444 gc_buffer_colorcodes
= buffer_colorcodes
;
445 gc_buffer_columns
= buffer_columns
;
446 gc_buffer_rows
= buffer_rows
;
447 gc_buffer_size
= buffer_size
;
451 VCPUTC_LOCK_UNLOCK( );
454 gc_ops
.clear_screen(gc_x
, gc_y
, 0, vinfo
.v_rows
, 2);
455 gc_ops
.show_cursor(gc_x
, gc_y
);
459 disableConsoleOutput
= FALSE
;
464 gc_hide_cursor(unsigned int xx
, unsigned int yy
)
466 if ( xx
< gc_buffer_columns
&& yy
< gc_buffer_rows
)
468 uint32_t index
= (yy
* gc_buffer_columns
) + xx
;
469 unsigned char attribute
= gc_buffer_attributes
[index
];
470 unsigned char character
= gc_buffer_characters
[index
];
471 unsigned char colorcode
= gc_buffer_colorcodes
[index
];
472 unsigned char colorcodesave
= gc_color_code
;
474 gc_update_color(COLOR_CODE_GET(colorcode
, TRUE
), TRUE
);
475 gc_update_color(COLOR_CODE_GET(colorcode
, FALSE
), FALSE
);
477 gc_ops
.paint_char(xx
, yy
, character
, attribute
, 0, 0);
479 gc_update_color(COLOR_CODE_GET(colorcodesave
, TRUE
), TRUE
);
480 gc_update_color(COLOR_CODE_GET(colorcodesave
, FALSE
), FALSE
);
484 gc_ops
.hide_cursor(xx
, yy
);
489 gc_initialize(struct vc_info
* info
)
491 if ( gc_initialized
== FALSE
)
496 gc_initialized
= TRUE
;
499 gc_ops
.initialize(info
);
506 gc_paint_char(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
)
508 if ( xx
< gc_buffer_columns
&& yy
< gc_buffer_rows
)
510 uint32_t index
= (yy
* gc_buffer_columns
) + xx
;
512 gc_buffer_attributes
[index
] = attrs
;
513 gc_buffer_characters
[index
] = ch
;
514 gc_buffer_colorcodes
[index
] = gc_color_code
;
517 gc_ops
.paint_char(xx
, yy
, ch
, attrs
, 0, 0);
524 return; /* ignore null characters */
526 switch (gc_vt100state
) {
527 default:gc_vt100state
= ESnormal
; /* FALLTHROUGH */
547 gc_putc_charsizecmd(ch
);
550 gc_putc_charsetcmd(0, ch
);
553 gc_putc_charsetcmd(1, ch
);
557 if (gc_x
>= vinfo
.v_columns
) {
558 if (0 == vinfo
.v_columns
)
561 gc_x
= vinfo
.v_columns
- 1;
563 if (gc_y
>= vinfo
.v_rows
) {
564 if (0 == vinfo
.v_rows
)
567 gc_y
= vinfo
.v_rows
- 1;
572 gc_putc_askcmd(unsigned char ch
)
574 if (ch
>= '0' && ch
<= '9') {
575 gc_par
[gc_numpars
] = (10*gc_par
[gc_numpars
]) + (ch
-'0');
578 gc_vt100state
= ESnormal
;
582 gc_relative_origin
= ch
== 'h';
584 case 7: /* wrap around mode h=1, l=0*/
585 gc_wrap_mode
= ch
== 'h';
594 gc_putc_charsetcmd(int charset
, unsigned char ch
)
596 gc_vt100state
= ESnormal
;
602 gc_charset
[charset
] = 0;
604 case '0' : /* Graphic characters */
606 gc_charset
[charset
] = 0x21;
613 gc_putc_charsizecmd(unsigned char ch
)
615 gc_vt100state
= ESnormal
;
623 case '8' : /* fill 'E's */
626 for (yy
= 0; yy
< vinfo
.v_rows
; yy
++)
627 for (xx
= 0; xx
< vinfo
.v_columns
; xx
++)
628 gc_paint_char(xx
, yy
, 'E', ATTR_NONE
);
636 gc_putc_esc(unsigned char ch
)
638 gc_vt100state
= ESnormal
;
642 gc_vt100state
= ESsquare
;
644 case 'c': /* Reset terminal */
646 gc_clear_screen(gc_x
, gc_y
, 0, vinfo
.v_rows
, 2);
649 case 'D': /* Line feed */
651 if (gc_y
>= gc_scrreg_bottom
-1) {
652 gc_scroll_up(1, gc_scrreg_top
, gc_scrreg_bottom
);
653 gc_y
= gc_scrreg_bottom
- 1;
657 if (ch
== 'E') gc_x
= 0;
659 case 'H': /* Set tab stop */
660 gc_tab_stops
[gc_x
] = 1;
662 case 'M': /* Cursor up */
663 if (gc_y
<= gc_scrreg_top
) {
664 gc_scroll_down(1, gc_scrreg_top
, gc_scrreg_bottom
);
665 gc_y
= gc_scrreg_top
;
673 case '7': /* Save cursor */
676 gc_saveattr
= gc_attr
;
677 gc_save_charset_s
= gc_charset_select
;
678 gc_charset_save
[0] = gc_charset
[0];
679 gc_charset_save
[1] = gc_charset
[1];
681 case '8': /* Restore cursor */
684 gc_attr
= gc_saveattr
;
685 gc_charset_select
= gc_save_charset_s
;
686 gc_charset
[0] = gc_charset_save
[0];
687 gc_charset
[1] = gc_charset_save
[1];
689 case 'Z': /* return terminal ID */
691 case '#': /* change characters height */
692 gc_vt100state
= EScharsize
;
695 gc_vt100state
= ESsetG0
;
697 case ')': /* character set sequence */
698 gc_vt100state
= ESsetG1
;
703 /* Rest not supported */
710 gc_putc_getpars(unsigned char ch
)
713 gc_vt100state
= ESask
;
717 gc_vt100state
= ESnormal
;
721 if (ch
== ';' && gc_numpars
< MAXPARS
- 1) {
724 if (ch
>= '0' && ch
<= '9') {
725 gc_par
[gc_numpars
] *= 10;
726 gc_par
[gc_numpars
] += ch
- '0';
729 gc_vt100state
= ESgotpars
;
735 gc_putc_gotpars(unsigned char ch
)
740 /* special case for vttest for handling cursor
741 movement in escape sequences */
743 gc_vt100state
= ESgotpars
;
746 gc_vt100state
= ESnormal
;
749 gc_y
-= gc_par
[0] ? gc_par
[0] : 1;
750 if (gc_y
< gc_scrreg_top
)
751 gc_y
= gc_scrreg_top
;
754 gc_y
+= gc_par
[0] ? gc_par
[0] : 1;
755 if (gc_y
>= gc_scrreg_bottom
)
756 gc_y
= gc_scrreg_bottom
- 1;
758 case 'C': /* Right */
759 gc_x
+= gc_par
[0] ? gc_par
[0] : 1;
760 if (gc_x
>= vinfo
.v_columns
)
761 gc_x
= vinfo
.v_columns
-1;
764 if (gc_par
[0] > gc_x
)
771 case 'H': /* Set cursor position */
773 gc_x
= gc_par
[1] ? gc_par
[1] - 1 : 0;
774 gc_y
= gc_par
[0] ? gc_par
[0] - 1 : 0;
775 if (gc_relative_origin
)
776 gc_y
+= gc_scrreg_top
;
777 gc_hanging_cursor
= 0;
779 case 'X': /* clear p1 characters */
781 for (i
= gc_x
; i
< gc_x
+ gc_par
[0]; i
++)
782 gc_paint_char(i
, gc_y
, ' ', ATTR_NONE
);
785 case 'J': /* Clear part of screen */
786 gc_clear_screen(gc_x
, gc_y
, 0, vinfo
.v_rows
, gc_par
[0]);
788 case 'K': /* Clear part of line */
789 gc_clear_line(gc_x
, gc_y
, gc_par
[0]);
791 case 'g': /* tab stops */
794 case 2: /* reset tab stops */
795 /* gc_reset_tabs(); */
797 case 3: /* Clear every tabs */
799 for (i
= 0; i
<= vinfo
.v_columns
; i
++)
804 gc_tab_stops
[gc_x
] = 0;
808 case 'm': /* Set attribute */
809 for (i
= 0; i
< gc_numpars
; i
++) {
813 gc_update_color(COLOR_BACKGROUND
, FALSE
);
814 gc_update_color(COLOR_FOREGROUND
, TRUE
);
817 gc_attr
|= ATTR_BOLD
;
820 gc_attr
|= ATTR_UNDER
;
823 gc_attr
|= ATTR_REVERSE
;
826 gc_attr
&= ~ATTR_BOLD
;
829 gc_attr
&= ~ATTR_UNDER
;
832 gc_attr
&= ~ATTR_REVERSE
;
835 case 25: /* blink/no blink */
838 if (gc_par
[i
] >= 30 && gc_par
[i
] <= 37)
839 gc_update_color(gc_par
[i
] - 30, TRUE
);
840 if (gc_par
[i
] >= 40 && gc_par
[i
] <= 47)
841 gc_update_color(gc_par
[i
] - 40, FALSE
);
846 case 'r': /* Set scroll region */
848 /* ensure top < bottom, and both within limits */
849 if ((gc_numpars
> 0) && (gc_par
[0] < vinfo
.v_rows
)) {
850 gc_scrreg_top
= gc_par
[0] ? gc_par
[0] - 1 : 0;
854 if ((gc_numpars
> 1) && (gc_par
[1] <= vinfo
.v_rows
) && (gc_par
[1] > gc_par
[0])) {
855 gc_scrreg_bottom
= gc_par
[1];
856 if (gc_scrreg_bottom
> vinfo
.v_rows
)
857 gc_scrreg_bottom
= vinfo
.v_rows
;
859 gc_scrreg_bottom
= vinfo
.v_rows
;
861 if (gc_relative_origin
)
862 gc_y
= gc_scrreg_top
;
869 gc_putc_normal(unsigned char ch
)
872 case '\a': /* Beep */
874 case 127: /* Delete */
875 case '\b': /* Backspace */
876 if (gc_hanging_cursor
) {
877 gc_hanging_cursor
= 0;
884 while (gc_x
< vinfo
.v_columns
&& !gc_tab_stops
[++gc_x
]);
885 if (gc_x
>= vinfo
.v_columns
)
886 gc_x
= vinfo
.v_columns
-1;
890 case '\n': /* Line feed */
891 if (gc_y
>= gc_scrreg_bottom
-1 ) {
892 gc_scroll_up(1, gc_scrreg_top
, gc_scrreg_bottom
);
893 gc_y
= gc_scrreg_bottom
- 1;
898 case '\r': /* Carriage return */
900 gc_hanging_cursor
= 0;
902 case 0x0e: /* Select G1 charset (Control-N) */
903 gc_charset_select
= 1;
905 case 0x0f: /* Select G0 charset (Control-O) */
906 gc_charset_select
= 0;
908 case 0x18 : /* CAN : cancel */
909 case 0x1A : /* like cancel */
910 /* well, i do nothing here, may be later */
912 case '\033': /* Escape */
913 gc_vt100state
= ESesc
;
914 gc_hanging_cursor
= 0;
918 if (gc_hanging_cursor
) {
920 if (gc_y
>= gc_scrreg_bottom
-1 ) {
921 gc_scroll_up(1, gc_scrreg_top
, gc_scrreg_bottom
);
922 gc_y
= gc_scrreg_bottom
- 1;
926 gc_hanging_cursor
= 0;
928 gc_paint_char(gc_x
, gc_y
, (ch
>= 0x60 && ch
<= 0x7f) ? ch
+ gc_charset
[gc_charset_select
]
930 if (gc_x
== vinfo
.v_columns
- 1) {
931 gc_hanging_cursor
= gc_wrap_mode
;
942 gc_putc_square(unsigned char ch
)
946 for (i
= 0; i
< MAXPARS
; i
++) {
951 gc_vt100state
= ESgetpars
;
958 gc_reset_screen(void)
969 for (i
= 0; i
<= vinfo
.v_columns
; i
++) {
970 gc_tab_stops
[i
] = ((i
% 8) == 0);
980 gc_scrreg_bottom
= vinfo
.v_rows
;
982 gc_charset
[0] = gc_charset
[1] = 0;
983 gc_charset_select
= 0;
985 gc_relative_origin
= 0;
986 gc_update_color(COLOR_BACKGROUND
, FALSE
);
987 gc_update_color(COLOR_FOREGROUND
, TRUE
);
991 gc_scroll_down(int num
, unsigned int top
, unsigned int bottom
)
993 if (!gc_buffer_size
) return;
995 if ( bottom
<= gc_buffer_rows
)
997 unsigned char colorcodesave
= gc_color_code
;
998 uint32_t column
, row
;
999 uint32_t index
, jump
;
1001 jump
= num
* gc_buffer_columns
;
1003 for ( row
= bottom
- 1 ; row
>= top
+ num
; row
-- )
1005 index
= row
* gc_buffer_columns
;
1007 for ( column
= 0 ; column
< gc_buffer_columns
; index
++, column
++ )
1009 if ( gc_buffer_attributes
[index
] != gc_buffer_attributes
[index
- jump
] ||
1010 gc_buffer_characters
[index
] != gc_buffer_characters
[index
- jump
] ||
1011 gc_buffer_colorcodes
[index
] != gc_buffer_colorcodes
[index
- jump
] )
1013 if ( gc_color_code
!= gc_buffer_colorcodes
[index
- jump
] )
1015 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes
[index
- jump
], TRUE
), TRUE
);
1016 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes
[index
- jump
], FALSE
), FALSE
);
1019 if ( gc_buffer_colorcodes
[index
] != gc_buffer_colorcodes
[index
- jump
] )
1021 gc_ops
.paint_char( /* xx */ column
,
1023 /* ch */ gc_buffer_characters
[index
- jump
],
1024 /* attrs */ gc_buffer_attributes
[index
- jump
],
1025 /* ch_previous */ 0,
1026 /* attrs_previous */ 0 );
1030 gc_ops
.paint_char( /* xx */ column
,
1032 /* ch */ gc_buffer_characters
[index
- jump
],
1033 /* attrs */ gc_buffer_attributes
[index
- jump
],
1034 /* ch_previous */ gc_buffer_characters
[index
],
1035 /* attrs_previous */ gc_buffer_attributes
[index
] );
1038 gc_buffer_attributes
[index
] = gc_buffer_attributes
[index
- jump
];
1039 gc_buffer_characters
[index
] = gc_buffer_characters
[index
- jump
];
1040 gc_buffer_colorcodes
[index
] = gc_buffer_colorcodes
[index
- jump
];
1045 if ( colorcodesave
!= gc_color_code
)
1047 gc_update_color(COLOR_CODE_GET(colorcodesave
, TRUE
), TRUE
);
1048 gc_update_color(COLOR_CODE_GET(colorcodesave
, FALSE
), FALSE
);
1051 /* Now set the freed up lines to the background colour */
1053 for ( row
= top
; row
< top
+ num
; row
++ )
1055 index
= row
* gc_buffer_columns
;
1057 for ( column
= 0 ; column
< gc_buffer_columns
; index
++, column
++ )
1059 if ( gc_buffer_attributes
[index
] != ATTR_NONE
||
1060 gc_buffer_characters
[index
] != ' ' ||
1061 gc_buffer_colorcodes
[index
] != gc_color_code
)
1063 if ( gc_buffer_colorcodes
[index
] != gc_color_code
)
1065 gc_ops
.paint_char( /* xx */ column
,
1068 /* attrs */ ATTR_NONE
,
1069 /* ch_previous */ 0,
1070 /* attrs_previous */ 0 );
1074 gc_ops
.paint_char( /* xx */ column
,
1077 /* attrs */ ATTR_NONE
,
1078 /* ch_previous */ gc_buffer_characters
[index
],
1079 /* attrs_previous */ gc_buffer_attributes
[index
] );
1082 gc_buffer_attributes
[index
] = ATTR_NONE
;
1083 gc_buffer_characters
[index
] = ' ';
1084 gc_buffer_colorcodes
[index
] = gc_color_code
;
1091 gc_ops
.scroll_down(num
, top
, bottom
);
1093 /* Now set the freed up lines to the background colour */
1095 gc_clear_screen(vinfo
.v_columns
- 1, top
+ num
- 1, top
, bottom
, 1);
1100 gc_scroll_up(int num
, unsigned int top
, unsigned int bottom
)
1102 if (!gc_buffer_size
) return;
1104 if ( bottom
<= gc_buffer_rows
)
1106 unsigned char colorcodesave
= gc_color_code
;
1107 uint32_t column
, row
;
1108 uint32_t index
, jump
;
1110 jump
= num
* gc_buffer_columns
;
1112 for ( row
= top
; row
< bottom
- num
; row
++ )
1114 index
= row
* gc_buffer_columns
;
1116 for ( column
= 0 ; column
< gc_buffer_columns
; index
++, column
++ )
1118 if ( gc_buffer_attributes
[index
] != gc_buffer_attributes
[index
+ jump
] ||
1119 gc_buffer_characters
[index
] != gc_buffer_characters
[index
+ jump
] ||
1120 gc_buffer_colorcodes
[index
] != gc_buffer_colorcodes
[index
+ jump
] )
1122 if ( gc_color_code
!= gc_buffer_colorcodes
[index
+ jump
] )
1124 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes
[index
+ jump
], TRUE
), TRUE
);
1125 gc_update_color(COLOR_CODE_GET(gc_buffer_colorcodes
[index
+ jump
], FALSE
), FALSE
);
1128 if ( gc_buffer_colorcodes
[index
] != gc_buffer_colorcodes
[index
+ jump
] )
1130 gc_ops
.paint_char( /* xx */ column
,
1132 /* ch */ gc_buffer_characters
[index
+ jump
],
1133 /* attrs */ gc_buffer_attributes
[index
+ jump
],
1134 /* ch_previous */ 0,
1135 /* attrs_previous */ 0 );
1139 gc_ops
.paint_char( /* xx */ column
,
1141 /* ch */ gc_buffer_characters
[index
+ jump
],
1142 /* attrs */ gc_buffer_attributes
[index
+ jump
],
1143 /* ch_previous */ gc_buffer_characters
[index
],
1144 /* attrs_previous */ gc_buffer_attributes
[index
] );
1147 gc_buffer_attributes
[index
] = gc_buffer_attributes
[index
+ jump
];
1148 gc_buffer_characters
[index
] = gc_buffer_characters
[index
+ jump
];
1149 gc_buffer_colorcodes
[index
] = gc_buffer_colorcodes
[index
+ jump
];
1154 if ( colorcodesave
!= gc_color_code
)
1156 gc_update_color(COLOR_CODE_GET(colorcodesave
, TRUE
), TRUE
);
1157 gc_update_color(COLOR_CODE_GET(colorcodesave
, FALSE
), FALSE
);
1160 /* Now set the freed up lines to the background colour */
1162 for ( row
= bottom
- num
; row
< bottom
; row
++ )
1164 index
= row
* gc_buffer_columns
;
1166 for ( column
= 0 ; column
< gc_buffer_columns
; index
++, column
++ )
1168 if ( gc_buffer_attributes
[index
] != ATTR_NONE
||
1169 gc_buffer_characters
[index
] != ' ' ||
1170 gc_buffer_colorcodes
[index
] != gc_color_code
)
1172 if ( gc_buffer_colorcodes
[index
] != gc_color_code
)
1174 gc_ops
.paint_char( /* xx */ column
,
1177 /* attrs */ ATTR_NONE
,
1178 /* ch_previous */ 0,
1179 /* attrs_previous */ 0 );
1183 gc_ops
.paint_char( /* xx */ column
,
1186 /* attrs */ ATTR_NONE
,
1187 /* ch_previous */ gc_buffer_characters
[index
],
1188 /* attrs_previous */ gc_buffer_attributes
[index
] );
1191 gc_buffer_attributes
[index
] = ATTR_NONE
;
1192 gc_buffer_characters
[index
] = ' ';
1193 gc_buffer_colorcodes
[index
] = gc_color_code
;
1200 gc_ops
.scroll_up(num
, top
, bottom
);
1202 /* Now set the freed up lines to the background colour */
1204 gc_clear_screen(0, bottom
- num
, top
, bottom
, 0);
1209 gc_show_cursor(unsigned int xx
, unsigned int yy
)
1211 if ( xx
< gc_buffer_columns
&& yy
< gc_buffer_rows
)
1213 uint32_t index
= (yy
* gc_buffer_columns
) + xx
;
1214 unsigned char attribute
= gc_buffer_attributes
[index
];
1215 unsigned char character
= gc_buffer_characters
[index
];
1216 unsigned char colorcode
= gc_buffer_colorcodes
[index
];
1217 unsigned char colorcodesave
= gc_color_code
;
1219 gc_update_color(COLOR_CODE_GET(colorcode
, FALSE
), TRUE
);
1220 gc_update_color(COLOR_CODE_GET(colorcode
, TRUE
), FALSE
);
1222 gc_ops
.paint_char(xx
, yy
, character
, attribute
, 0, 0);
1224 gc_update_color(COLOR_CODE_GET(colorcodesave
, TRUE
), TRUE
);
1225 gc_update_color(COLOR_CODE_GET(colorcodesave
, FALSE
), FALSE
);
1229 gc_ops
.show_cursor(xx
, yy
);
1234 gc_update_color(int color
, boolean_t fore
)
1236 gc_color_code
= COLOR_CODE_SET(gc_color_code
, color
, fore
);
1237 gc_ops
.update_color(color
, fore
);
1241 vcputc(__unused
int l
, __unused
int u
, int c
)
1243 if ( gc_enabled
|| debug_mode
)
1250 gc_hide_cursor(gc_x
, gc_y
);
1252 gc_show_cursor(gc_x
, gc_y
);
1254 VCPUTC_LOCK_UNLOCK();
1260 * Video Console (Back-End)
1261 * ------------------------
1265 * For the color support (Michel Pollet)
1267 static unsigned char vc_color_index_table
[33] =
1268 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1269 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2 };
1271 static uint32_t vc_colors
[8][4] = {
1272 { 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000 }, /* black */
1273 { 0x23232323, 0x7C007C00, 0x00FF0000, 0x3FF00000 }, /* red */
1274 { 0xb9b9b9b9, 0x03e003e0, 0x0000FF00, 0x000FFC00 }, /* green */
1275 { 0x05050505, 0x7FE07FE0, 0x00FFFF00, 0x3FFFFC00 }, /* yellow */
1276 { 0xd2d2d2d2, 0x001f001f, 0x000000FF, 0x000003FF }, /* blue */
1277 // { 0x80808080, 0x31933193, 0x00666699, 0x00000000 }, /* blue */
1278 { 0x18181818, 0x7C1F7C1F, 0x00FF00FF, 0x3FF003FF }, /* magenta */
1279 { 0xb4b4b4b4, 0x03FF03FF, 0x0000FFFF, 0x000FFFFF }, /* cyan */
1280 { 0x00000000, 0x7FFF7FFF, 0x00FFFFFF, 0x3FFFFFFF } /* white */
1283 static uint32_t vc_color_fore
= 0;
1284 static uint32_t vc_color_back
= 0;
1287 * New Rendering code from Michel Pollet
1290 /* Rendered Font Buffer */
1291 static unsigned char *vc_rendered_font
= NULL
;
1293 /* Rendered Font Size */
1294 static uint32_t vc_rendered_font_size
= 0;
1296 /* Size of a character in the table (bytes) */
1297 static int vc_rendered_char_size
= 0;
1299 #define REN_MAX_DEPTH 32
1300 static unsigned char vc_rendered_char
[ISO_CHAR_HEIGHT
* ((REN_MAX_DEPTH
/ 8) * ISO_CHAR_WIDTH
)];
1303 vc_clear_screen(unsigned int xx
, unsigned int yy
, unsigned int scrreg_top
,
1304 unsigned int scrreg_bottom
, int which
)
1306 uint32_t *p
, *endp
, *row
;
1308 int rowline
, rowlongs
;
1313 linelongs
= vinfo
.v_rowbytes
* (ISO_CHAR_HEIGHT
>> 2);
1314 rowline
= vinfo
.v_rowscanbytes
>> 2;
1315 rowlongs
= vinfo
.v_rowbytes
>> 2;
1317 p
= (uint32_t*) vinfo
.v_baseaddr
;
1318 endp
= (uint32_t*) vinfo
.v_baseaddr
;
1321 case 0: /* To end of screen */
1322 gc_clear_line(xx
, yy
, 0);
1323 if (yy
< scrreg_bottom
- 1) {
1324 p
+= (yy
+ 1) * linelongs
;
1325 endp
+= scrreg_bottom
* linelongs
;
1328 case 1: /* To start of screen */
1329 gc_clear_line(xx
, yy
, 1);
1330 if (yy
> scrreg_top
) {
1331 p
+= scrreg_top
* linelongs
;
1332 endp
+= yy
* linelongs
;
1335 case 2: /* Whole screen */
1336 p
+= scrreg_top
* linelongs
;
1337 if (scrreg_bottom
== vinfo
.v_rows
) {
1338 endp
+= rowlongs
* vinfo
.v_height
;
1340 endp
+= scrreg_bottom
* linelongs
;
1345 for (row
= p
; row
< endp
; row
+= rowlongs
) {
1346 for (col
= 0; col
< rowline
; col
++)
1347 *(row
+col
) = vc_color_back
;
1352 vc_initialize(__unused
struct vc_info
* vinfo_p
)
1355 vinfo
.v_rows
= vinfo
.v_height
/ ISO_CHAR_HEIGHT
;
1356 vinfo
.v_columns
= vinfo
.v_width
/ ISO_CHAR_WIDTH
;
1357 vinfo
.v_rowscanbytes
= ((vinfo
.v_depth
+ 7) / 8) * vinfo
.v_width
;
1361 vc_render_char(unsigned char ch
, unsigned char *renderptr
, short newdepth
)
1364 unsigned char *charptr
;
1365 unsigned short *shortptr
;
1367 } current
; /* current place in rendered font, multiple types. */
1368 unsigned char *theChar
; /* current char in iso_font */
1371 current
.charptr
= renderptr
;
1372 theChar
= iso_font
+ (ch
* ISO_CHAR_HEIGHT
);
1374 for (line
= 0; line
< ISO_CHAR_HEIGHT
; line
++) {
1375 unsigned char mask
= 1;
1379 *current
.charptr
++ = (*theChar
& mask
) ? 0xFF : 0;
1382 *current
.shortptr
++ = (*theChar
& mask
) ? 0xFFFF : 0;
1387 *current
.longptr
++ = (*theChar
& mask
) ? 0xFFFFFFFF : 0;
1391 } while (mask
); /* while the single bit drops to the right */
1397 vc_paint_char_8(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
,
1398 __unused
unsigned char ch_previous
, __unused
int attrs_previous
)
1404 if (vc_rendered_font
) {
1405 theChar
= (uint32_t*)(vc_rendered_font
+ (ch
* vc_rendered_char_size
));
1407 vc_render_char(ch
, vc_rendered_char
, 8);
1408 theChar
= (uint32_t*)(vc_rendered_char
);
1410 where
= (uint32_t*)(vinfo
.v_baseaddr
+
1411 (yy
* ISO_CHAR_HEIGHT
* vinfo
.v_rowbytes
) +
1412 (xx
* ISO_CHAR_WIDTH
));
1414 if (!attrs
) for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* No attr? FLY !*/
1415 uint32_t *store
= where
;
1417 for (x
= 0; x
< 2; x
++) {
1418 uint32_t val
= *theChar
++;
1419 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1423 where
= (uint32_t*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1424 } else for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* a little slower */
1425 uint32_t *store
= where
, lastpixel
= 0;
1427 for (x
= 0 ; x
< 2; x
++) {
1428 uint32_t val
= *theChar
++, save
= val
;
1429 if (attrs
& ATTR_BOLD
) { /* bold support */
1430 if (lastpixel
&& !(save
& 0xFF000000))
1432 if ((save
& 0xFFFF0000) == 0xFF000000)
1434 if ((save
& 0x00FFFF00) == 0x00FF0000)
1436 if ((save
& 0x0000FFFF) == 0x0000FF00)
1439 if (attrs
& ATTR_REVERSE
) val
= ~val
;
1440 if (attrs
& ATTR_UNDER
&& i
== ISO_CHAR_HEIGHT
-1) val
= ~val
;
1442 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1444 lastpixel
= save
& 0xff;
1447 where
= (uint32_t*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1453 vc_paint_char_16(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
,
1454 __unused
unsigned char ch_previous
,
1455 __unused
int attrs_previous
)
1461 if (vc_rendered_font
) {
1462 theChar
= (uint32_t*)(vc_rendered_font
+ (ch
* vc_rendered_char_size
));
1464 vc_render_char(ch
, vc_rendered_char
, 16);
1465 theChar
= (uint32_t*)(vc_rendered_char
);
1467 where
= (uint32_t*)(vinfo
.v_baseaddr
+
1468 (yy
* ISO_CHAR_HEIGHT
* vinfo
.v_rowbytes
) +
1469 (xx
* ISO_CHAR_WIDTH
* 2));
1471 if (!attrs
) for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* No attrs ? FLY ! */
1472 uint32_t *store
= where
;
1474 for (x
= 0; x
< 4; x
++) {
1475 uint32_t val
= *theChar
++;
1476 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1480 where
= (uint32_t*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1481 } else for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* a little bit slower */
1482 uint32_t *store
= where
, lastpixel
= 0;
1484 for (x
= 0 ; x
< 4; x
++) {
1485 uint32_t val
= *theChar
++, save
= val
;
1486 if (attrs
& ATTR_BOLD
) { /* bold support */
1487 if (save
== 0xFFFF0000) val
|= 0xFFFF;
1488 else if (lastpixel
&& !(save
& 0xFFFF0000))
1491 if (attrs
& ATTR_REVERSE
) val
= ~val
;
1492 if (attrs
& ATTR_UNDER
&& i
== ISO_CHAR_HEIGHT
-1) val
= ~val
;
1494 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1497 lastpixel
= save
& 0x7fff;
1500 where
= (uint32_t*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1506 vc_paint_char_32(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
,
1507 unsigned char ch_previous
, int attrs_previous
)
1510 uint32_t *theCharPrevious
;
1514 if (vc_rendered_font
) {
1515 theChar
= (uint32_t*)(vc_rendered_font
+ (ch
* vc_rendered_char_size
));
1516 theCharPrevious
= (uint32_t*)(vc_rendered_font
+ (ch_previous
* vc_rendered_char_size
));
1518 vc_render_char(ch
, vc_rendered_char
, 32);
1519 theChar
= (uint32_t*)(vc_rendered_char
);
1520 theCharPrevious
= NULL
;
1523 theCharPrevious
= NULL
;
1525 if (attrs_previous
) {
1526 theCharPrevious
= NULL
;
1528 where
= (uint32_t*)(vinfo
.v_baseaddr
+
1529 (yy
* ISO_CHAR_HEIGHT
* vinfo
.v_rowbytes
) +
1530 (xx
* ISO_CHAR_WIDTH
* 4));
1532 if (!attrs
) for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* No attrs ? FLY ! */
1533 uint32_t *store
= where
;
1535 for (x
= 0; x
< 8; x
++) {
1536 uint32_t val
= *theChar
++;
1537 if (theCharPrevious
== NULL
|| val
!= *theCharPrevious
++ ) {
1538 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1545 where
= (uint32_t *)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1546 } else for (i
= 0; i
< ISO_CHAR_HEIGHT
; i
++) { /* a little slower */
1547 uint32_t *store
= where
, lastpixel
= 0;
1549 for (x
= 0 ; x
< 8; x
++) {
1550 uint32_t val
= *theChar
++, save
= val
;
1551 if (attrs
& ATTR_BOLD
) { /* bold support */
1552 if (lastpixel
&& !save
)
1555 if (attrs
& ATTR_REVERSE
) val
= ~val
;
1556 if (attrs
& ATTR_UNDER
&& i
== ISO_CHAR_HEIGHT
-1) val
= ~val
;
1558 val
= (vc_color_back
& ~val
) | (vc_color_fore
& val
);
1563 where
= (uint32_t*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1569 vc_paint_char(unsigned int xx
, unsigned int yy
, unsigned char ch
, int attrs
,
1570 unsigned char ch_previous
, int attrs_previous
)
1575 switch(vinfo
.v_depth
) {
1577 vc_paint_char_8(xx
, yy
, ch
, attrs
, ch_previous
, attrs_previous
);
1580 vc_paint_char_16(xx
, yy
, ch
, attrs
, ch_previous
,
1585 vc_paint_char_32(xx
, yy
, ch
, attrs
, ch_previous
,
1592 vc_render_font(short newdepth
)
1594 static short olddepth
= 0;
1596 int charindex
; /* index in ISO font */
1597 unsigned char *rendered_font
;
1598 unsigned int rendered_font_size
;
1599 int rendered_char_size
;
1602 if (vm_initialized
== FALSE
) {
1603 return; /* nothing to do */
1605 if (olddepth
== newdepth
&& vc_rendered_font
) {
1606 return; /* nothing to do */
1612 rendered_font
= vc_rendered_font
;
1613 rendered_font_size
= vc_rendered_font_size
;
1614 rendered_char_size
= vc_rendered_char_size
;
1616 vc_rendered_font
= NULL
;
1617 vc_rendered_font_size
= 0;
1618 vc_rendered_char_size
= 0;
1620 VCPUTC_LOCK_UNLOCK();
1623 if (rendered_font
) {
1624 kfree(rendered_font
, rendered_font_size
);
1625 rendered_font
= NULL
;
1629 rendered_char_size
= ISO_CHAR_HEIGHT
* (((newdepth
+ 7) / 8) * ISO_CHAR_WIDTH
);
1630 rendered_font_size
= (ISO_CHAR_MAX
-ISO_CHAR_MIN
+1) * rendered_char_size
;
1631 rendered_font
= (unsigned char *) kalloc(rendered_font_size
);
1634 if (rendered_font
== NULL
) {
1638 for (charindex
= ISO_CHAR_MIN
; charindex
<= ISO_CHAR_MAX
; charindex
++) {
1639 vc_render_char(charindex
, rendered_font
+ (charindex
* rendered_char_size
), newdepth
);
1642 olddepth
= newdepth
;
1647 vc_rendered_font
= rendered_font
;
1648 vc_rendered_font_size
= rendered_font_size
;
1649 vc_rendered_char_size
= rendered_char_size
;
1651 VCPUTC_LOCK_UNLOCK();
1656 vc_enable(boolean_t enable
)
1658 vc_render_font(enable
? vinfo
.v_depth
: 0);
1662 vc_reverse_cursor(unsigned int xx
, unsigned int yy
)
1670 where
= (uint32_t*)(vinfo
.v_baseaddr
+
1671 (yy
* ISO_CHAR_HEIGHT
* vinfo
.v_rowbytes
) +
1672 (xx
/** ISO_CHAR_WIDTH*/ * vinfo
.v_depth
));
1673 for (line
= 0; line
< ISO_CHAR_HEIGHT
; line
++) {
1674 switch (vinfo
.v_depth
) {
1676 where
[0] = ~where
[0];
1677 where
[1] = ~where
[1];
1680 for (col
= 0; col
< 4; col
++)
1681 where
[col
] = ~where
[col
];
1684 for (col
= 0; col
< 8; col
++)
1685 where
[col
] = ~where
[col
];
1688 where
= (uint32_t*)(((unsigned char*)where
)+vinfo
.v_rowbytes
);
1693 vc_scroll_down(int num
, unsigned int scrreg_top
, unsigned int scrreg_bottom
)
1695 uint32_t *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
1700 linelongs
= vinfo
.v_rowbytes
* (ISO_CHAR_HEIGHT
>> 2);
1701 rowline
= vinfo
.v_rowbytes
>> 2;
1702 rowscanline
= vinfo
.v_rowscanbytes
>> 2;
1704 to
= (uint32_t *) vinfo
.v_baseaddr
+ (linelongs
* scrreg_bottom
)
1705 - (rowline
- rowscanline
);
1706 from
= to
- (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
1708 i
= (scrreg_bottom
- scrreg_top
) - num
;
1711 for (line
= 0; line
< ISO_CHAR_HEIGHT
; line
++) {
1713 * Only copy what is displayed
1715 video_scroll_down(from
,
1716 (from
-(vinfo
.v_rowscanbytes
>> 2)),
1726 vc_scroll_up(int num
, unsigned int scrreg_top
, unsigned int scrreg_bottom
)
1728 uint32_t *from
, *to
, linelongs
, i
, line
, rowline
, rowscanline
;
1733 linelongs
= vinfo
.v_rowbytes
* (ISO_CHAR_HEIGHT
>> 2);
1734 rowline
= vinfo
.v_rowbytes
>> 2;
1735 rowscanline
= vinfo
.v_rowscanbytes
>> 2;
1737 to
= (uint32_t *) vinfo
.v_baseaddr
+ (scrreg_top
* linelongs
);
1738 from
= to
+ (linelongs
* num
); /* handle multiple line scroll (Michel Pollet) */
1740 i
= (scrreg_bottom
- scrreg_top
) - num
;
1743 for (line
= 0; line
< ISO_CHAR_HEIGHT
; line
++) {
1745 * Only copy what is displayed
1747 video_scroll_up(from
,
1748 (from
+(vinfo
.v_rowscanbytes
>> 2)),
1758 vc_update_color(int color
, boolean_t fore
)
1763 vc_color_fore
= vc_colors
[color
][vc_color_index_table
[vinfo
.v_depth
]];
1765 vc_color_back
= vc_colors
[color
][vc_color_index_table
[vinfo
.v_depth
]];
1770 * Video Console (Back-End): Icon Control
1771 * --------------------------------------
1774 struct vc_progress_element
{
1775 unsigned int version
;
1778 unsigned char count
;
1779 unsigned char res
[3];
1785 unsigned int res2
[3];
1786 unsigned char data
[0];
1788 typedef struct vc_progress_element vc_progress_element
;
1790 static vc_progress_element
* vc_progress
;
1791 static const unsigned char * vc_progress_data
;
1792 static const unsigned char * vc_progress_alpha
;
1793 static boolean_t vc_progress_enable
;
1794 static const unsigned char * vc_clut
;
1795 static const unsigned char * vc_clut8
;
1796 static unsigned char vc_revclut8
[256];
1797 static uint32_t vc_progress_interval
;
1798 static uint64_t vc_progress_deadline
;
1799 static thread_call_data_t vc_progress_call
;
1800 static boolean_t vc_needsave
;
1801 static void * vc_saveunder
;
1802 static vm_size_t vc_saveunder_len
;
1803 decl_simple_lock_data(,vc_progress_lock
)
1807 kDataIndexed
= 0x02,
1812 static void vc_blit_rect(int x
, int y
, int bx
,
1813 int width
, int height
,
1814 int sourceRow
, int backRow
,
1815 const unsigned char * dataPtr
,
1817 unsigned int flags
);
1818 static void vc_blit_rect_8(int x
, int y
, int bx
,
1819 int width
, int height
,
1820 int sourceRow
, int backRow
,
1821 const unsigned char * dataPtr
,
1822 unsigned char * backBuffer
,
1823 unsigned int flags
);
1824 static void vc_blit_rect_16(int x
, int y
, int bx
,
1825 int width
, int height
,
1826 int sourceRow
, int backRow
,
1827 const unsigned char * dataPtr
,
1828 unsigned short * backBuffer
,
1829 unsigned int flags
);
1830 static void vc_blit_rect_32(int x
, int y
, int bx
,
1831 int width
, int height
,
1832 int sourceRow
, int backRow
,
1833 const unsigned char * dataPtr
,
1834 unsigned int * backBuffer
,
1835 unsigned int flags
);
1836 static void vc_blit_rect_30(int x
, int y
, int bx
,
1837 int width
, int height
,
1838 int sourceRow
, int backRow
,
1839 const unsigned char * dataPtr
,
1840 unsigned int * backBuffer
,
1841 unsigned int flags
);
1842 extern void vc_display_icon( vc_progress_element
* desc
, const unsigned char * data
);
1843 extern void vc_progress_initialize( vc_progress_element
* desc
, const unsigned char * data
, const unsigned char * clut
);
1844 void vc_progress_set(boolean_t enable
, uint32_t vc_delay
);
1845 static void vc_progress_task( void * arg0
, void * arg
);
1847 static void vc_blit_rect(int x
, int y
, int bx
,
1848 int width
, int height
,
1849 int sourceRow
, int backRow
,
1850 const unsigned char * dataPtr
,
1857 switch( vinfo
.v_depth
) {
1859 if( vc_clut8
== vc_clut
)
1860 vc_blit_rect_8( x
, y
, bx
, width
, height
, sourceRow
, backRow
, dataPtr
, (unsigned char *) backBuffer
, flags
);
1863 vc_blit_rect_16( x
, y
, bx
, width
, height
, sourceRow
, backRow
, dataPtr
, (unsigned short *) backBuffer
, flags
);
1866 vc_blit_rect_32( x
, y
, bx
, width
, height
, sourceRow
, backRow
, dataPtr
, (unsigned int *) backBuffer
, flags
);
1869 vc_blit_rect_30( x
, y
, bx
, width
, height
, sourceRow
, backRow
, dataPtr
, (unsigned int *) backBuffer
, flags
);
1875 vc_blit_rect_8(int x
, int y
, __unused
int bx
,
1876 int width
, int height
,
1877 int sourceRow
, __unused
int backRow
,
1878 const unsigned char * dataPtr
,
1879 __unused
unsigned char * backBuffer
,
1880 __unused
unsigned int flags
)
1882 volatile unsigned short * dst
;
1884 unsigned int data
= 0, out
= 0;
1887 data
= (unsigned int)(uintptr_t)dataPtr
;
1888 dst
= (volatile unsigned short *) (vinfo
.v_baseaddr
+
1889 (y
* vinfo
.v_rowbytes
) +
1892 for( line
= 0; line
< height
; line
++)
1894 for( col
= 0; col
< width
; col
++)
1896 if (col
< sourceRow
)
1898 if (kDataAlpha
& flags
)
1899 out
= vc_revclut8
[data
];
1904 dst
= (volatile unsigned short *) (((volatile char*)dst
) + vinfo
.v_rowbytes
);
1905 if (sourceRow
> width
)
1906 dataPtr
+= sourceRow
- width
;
1910 /* For ARM, 16-bit is 565 (RGB); it is 1555 (XRGB) on other platforms */
1912 #define CLUT_MASK_R 0xf8
1913 #define CLUT_MASK_G 0xf8
1914 #define CLUT_MASK_B 0xf8
1915 #define CLUT_SHIFT_R << 7
1916 #define CLUT_SHIFT_G << 2
1917 #define CLUT_SHIFT_B >> 3
1918 #define MASK_R 0x7c00
1919 #define MASK_G 0x03e0
1920 #define MASK_B 0x001f
1921 #define MASK_R_8 0x3fc00
1922 #define MASK_G_8 0x01fe0
1923 #define MASK_B_8 0x000ff
1925 static void vc_blit_rect_16( int x
, int y
, int bx
,
1926 int width
, int height
,
1927 int sourceRow
, int backRow
,
1928 const unsigned char * dataPtr
,
1929 unsigned short * backPtr
,
1932 volatile unsigned short * dst
;
1934 unsigned int data
= 0, out
= 0, back
= 0;
1939 data
= (unsigned int)(uintptr_t)dataPtr
;
1940 dst
= (volatile unsigned short *) (vinfo
.v_baseaddr
+
1941 (y
* vinfo
.v_rowbytes
) +
1944 for( line
= 0; line
< height
; line
++)
1946 for( col
= 0; col
< width
; col
++)
1948 if (col
< sourceRow
)
1952 if (kSave
& flags
) {
1953 back
= *(dst
+ col
);
1958 if (kDataIndexed
& flags
) {
1959 out
= ( (CLUT_MASK_R
& (vc_clut
[data
*3 + 0])) CLUT_SHIFT_R
)
1960 | ( (CLUT_MASK_G
& (vc_clut
[data
*3 + 1])) CLUT_SHIFT_G
)
1961 | ( (CLUT_MASK_B
& (vc_clut
[data
*3 + 2])) CLUT_SHIFT_B
);
1962 } else if (kDataAlpha
& flags
) {
1963 out
= (((((back
& MASK_R
) * data
) + MASK_R_8
) >> 8) & MASK_R
)
1964 | (((((back
& MASK_G
) * data
) + MASK_G_8
) >> 8) & MASK_G
)
1965 | (((((back
& MASK_B
) * data
) + MASK_B_8
) >> 8) & MASK_B
);
1966 #ifdef CONFIG_VC_PROGRESS_WHITE
1967 out
+= (((0xff - data
) & CLUT_MASK_R
) CLUT_SHIFT_R
)
1968 | (((0xff - data
) & CLUT_MASK_G
) CLUT_SHIFT_G
)
1969 | (((0xff - data
) & CLUT_MASK_B
) CLUT_SHIFT_B
);
1975 dst
= (volatile unsigned short *) (((volatile char*)dst
) + vinfo
.v_rowbytes
);
1977 backPtr
+= backRow
- width
;
1978 if (sourceRow
> width
)
1979 dataPtr
+= sourceRow
- width
;
1983 static void vc_blit_rect_32(int x
, int y
, int bx
,
1984 int width
, int height
,
1985 int sourceRow
, int backRow
,
1986 const unsigned char * dataPtr
,
1987 unsigned int * backPtr
,
1990 volatile unsigned int * dst
;
1992 unsigned int data
= 0, out
= 0, back
= 0;
1997 data
= (unsigned int)(uintptr_t)dataPtr
;
1998 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
1999 (y
* vinfo
.v_rowbytes
) +
2002 for( line
= 0; line
< height
; line
++)
2004 for( col
= 0; col
< width
; col
++)
2006 if (col
< sourceRow
)
2010 if (kSave
& flags
) {
2011 back
= *(dst
+ col
);
2016 if (kDataIndexed
& flags
) {
2017 out
= (vc_clut
[data
*3 + 0] << 16)
2018 | (vc_clut
[data
*3 + 1] << 8)
2019 | (vc_clut
[data
*3 + 2]);
2020 } else if (kDataAlpha
& flags
) {
2021 out
= (((((back
& 0x00ff00ff) * data
) + 0x00ff00ff) >> 8) & 0x00ff00ff)
2022 | (((((back
& 0x0000ff00) * data
) + 0x0000ff00) >> 8) & 0x0000ff00);
2023 #ifdef CONFIG_VC_PROGRESS_WHITE
2024 out
+= ((0xff - data
) << 16)
2025 | ((0xff - data
) << 8)
2032 dst
= (volatile unsigned int *) (((volatile char*)dst
) + vinfo
.v_rowbytes
);
2034 backPtr
+= backRow
- width
;
2035 if (sourceRow
> width
)
2036 dataPtr
+= sourceRow
- width
;
2040 static void vc_blit_rect_30(int x
, int y
, int bx
,
2041 int width
, int height
,
2042 int sourceRow
, int backRow
,
2043 const unsigned char * dataPtr
,
2044 unsigned int * backPtr
,
2047 volatile unsigned int * dst
;
2049 unsigned int data
= 0, out
= 0, back
= 0;
2050 unsigned long long exp
;
2055 data
= (unsigned int)(uintptr_t)dataPtr
;
2056 dst
= (volatile unsigned int *) (vinfo
.v_baseaddr
+
2057 (y
* vinfo
.v_rowbytes
) +
2060 for( line
= 0; line
< height
; line
++)
2062 for( col
= 0; col
< width
; col
++)
2064 if (col
< sourceRow
)
2068 if (kSave
& flags
) {
2069 back
= *(dst
+ col
);
2074 if (kDataIndexed
& flags
) {
2075 out
= (vc_clut
[data
*3 + 0] << 22)
2076 | (vc_clut
[data
*3 + 1] << 12)
2077 | (vc_clut
[data
*3 + 2] << 2);
2078 } else if (kDataAlpha
& flags
) {
2080 exp
= (((((exp
& 0x3FF003FF) * data
) + 0x0FF000FF) >> 8) & 0x3FF003FF)
2081 | (((((exp
& 0x000FFC00) * data
) + 0x0003FC00) >> 8) & 0x000FFC00);
2082 out
= (unsigned int)exp
;
2083 #ifdef CONFIG_VC_PROGRESS_WHITE
2084 out
+= ((0xFF - data
) << 22)
2085 | ((0xFF - data
) << 12)
2086 | ((0xFF - data
) << 2);
2092 dst
= (volatile unsigned int *) (((volatile char*)dst
) + vinfo
.v_rowbytes
);
2094 backPtr
+= backRow
- width
;
2095 if (sourceRow
> width
)
2096 dataPtr
+= sourceRow
- width
;
2100 void vc_display_icon( vc_progress_element
* desc
,
2101 const unsigned char * data
)
2103 int x
, y
, width
, height
;
2105 if( vc_progress_enable
&& vc_clut
) {
2107 width
= desc
->width
;
2108 height
= desc
->height
;
2111 if( 1 & desc
->flags
) {
2112 x
+= ((vinfo
.v_width
- width
) / 2);
2113 y
+= ((vinfo
.v_height
- height
) / 2);
2115 vc_blit_rect( x
, y
, 0, width
, height
, width
, 0, data
, NULL
, kDataIndexed
);
2120 vc_progress_initialize( vc_progress_element
* desc
,
2121 const unsigned char * data
,
2122 const unsigned char * clut
)
2126 if( (!clut
) || (!desc
) || (!data
))
2131 simple_lock_init(&vc_progress_lock
, 0);
2134 vc_progress_data
= data
;
2135 if( 2 & vc_progress
->flags
)
2136 vc_progress_alpha
= vc_progress_data
2137 + vc_progress
->count
* vc_progress
->width
* vc_progress
->height
;
2139 vc_progress_alpha
= NULL
;
2141 thread_call_setup(&vc_progress_call
, vc_progress_task
, NULL
);
2143 clock_interval_to_absolutetime_interval(vc_progress
->time
, 1000 * 1000, &abstime
);
2144 vc_progress_interval
= (uint32_t)abstime
;
2148 vc_progress_set(boolean_t enable
, uint32_t vc_delay
)
2151 void *saveBuf
= NULL
;
2152 vm_size_t saveLen
= 0;
2155 unsigned char pdata8
;
2156 unsigned short pdata16
;
2157 unsigned short * buf16
;
2158 unsigned int pdata32
;
2159 unsigned int * buf32
;
2165 saveLen
= vc_progress
->width
* vc_progress
->height
* vinfo
.v_depth
/ 8;
2166 saveBuf
= kalloc( saveLen
);
2168 switch( vinfo
.v_depth
) {
2170 for( count
= 0; count
< 256; count
++) {
2171 vc_revclut8
[count
] = vc_clut
[0x01 * 3];
2172 pdata8
= (vc_clut
[0x01 * 3] * count
+ 0x0ff) >> 8;
2173 for( index
= 0; index
< 256; index
++) {
2174 if( (pdata8
== vc_clut
[index
* 3 + 0]) &&
2175 (pdata8
== vc_clut
[index
* 3 + 1]) &&
2176 (pdata8
== vc_clut
[index
* 3 + 2])) {
2177 vc_revclut8
[count
] = index
;
2182 memset( saveBuf
, 0x01, saveLen
);
2186 buf16
= (unsigned short *) saveBuf
;
2187 pdata16
= ((vc_clut
[0x01 * 3 + 0] & CLUT_MASK_R
) CLUT_SHIFT_R
)
2188 | ((vc_clut
[0x01 * 3 + 0] & CLUT_MASK_G
) CLUT_SHIFT_G
)
2189 | ((vc_clut
[0x01 * 3 + 0] & CLUT_MASK_B
) CLUT_SHIFT_B
);
2190 for( count
= 0; count
< saveLen
/ 2; count
++)
2191 buf16
[count
] = pdata16
;
2195 buf32
= (unsigned int *) saveBuf
;
2196 pdata32
= ((vc_clut
[0x01 * 3 + 0] & 0xff) << 16)
2197 | ((vc_clut
[0x01 * 3 + 1] & 0xff) << 8)
2198 | ((vc_clut
[0x01 * 3 + 2] & 0xff) << 0);
2199 for( count
= 0; count
< saveLen
/ 4; count
++)
2200 buf32
[count
] = pdata32
;
2206 simple_lock(&vc_progress_lock
);
2208 if( vc_progress_enable
!= enable
) {
2209 vc_progress_enable
= enable
;
2212 vc_saveunder
= saveBuf
;
2213 vc_saveunder_len
= saveLen
;
2217 clock_interval_to_deadline(vc_delay
,
2218 1000 * 1000 * 1000 /*second scale*/,
2219 &vc_progress_deadline
);
2220 thread_call_enter_delayed(&vc_progress_call
, vc_progress_deadline
);
2224 saveBuf
= vc_saveunder
;
2225 saveLen
= vc_saveunder_len
;
2226 vc_saveunder
= NULL
;
2227 vc_saveunder_len
= 0;
2230 thread_call_cancel(&vc_progress_call
);
2234 simple_unlock(&vc_progress_lock
);
2238 kfree( saveBuf
, saveLen
);
2243 vc_progress_task(__unused
void *arg0
, void *arg
)
2246 int count
= (int)(uintptr_t) arg
;
2247 int x
, y
, width
, height
;
2248 const unsigned char * data
;
2251 simple_lock(&vc_progress_lock
);
2253 if( vc_progress_enable
) {
2255 KERNEL_DEBUG_CONSTANT(0x7020008, count
, 0, 0, 0, 0);
2258 if( count
>= vc_progress
->count
)
2261 width
= vc_progress
->width
;
2262 height
= vc_progress
->height
;
2263 x
= vc_progress
->dx
;
2264 y
= vc_progress
->dy
;
2265 data
= vc_progress_data
;
2266 data
+= count
* width
* height
;
2267 if( 1 & vc_progress
->flags
) {
2268 x
+= ((vinfo
.v_width
- width
) / 2);
2269 y
+= ((vinfo
.v_height
- height
) / 2);
2271 vc_blit_rect( x
, y
, 0,
2272 width
, height
, width
, width
,
2274 kDataAlpha
| (vc_needsave
? kSave
: 0) );
2275 vc_needsave
= FALSE
;
2277 clock_deadline_for_periodic_event(vc_progress_interval
, mach_absolute_time(), &vc_progress_deadline
);
2278 thread_call_enter1_delayed(&vc_progress_call
, (void *)(uintptr_t)count
, vc_progress_deadline
);
2280 simple_unlock(&vc_progress_lock
);
2285 * Generic Console (Front-End): Master Control
2286 * -------------------------------------------
2289 #if defined (__i386__) || defined (__x86_64__)
2290 #include <pexpert/i386/boot.h>
2293 static boolean_t gc_acquired
= FALSE
;
2294 static boolean_t gc_graphics_boot
= FALSE
;
2295 static boolean_t gc_desire_text
= FALSE
;
2297 static unsigned int lastVideoPhys
= 0;
2298 static vm_offset_t lastVideoVirt
= 0;
2299 static vm_size_t lastVideoSize
= 0;
2300 static boolean_t lastVideoMapped
= FALSE
;
2303 initialize_screen(PE_Video
* boot_vinfo
, unsigned int op
)
2305 unsigned int fbsize
= 0;
2306 vm_offset_t newVideoVirt
= 0;
2307 boolean_t graphics_now
;
2312 struct vc_info new_vinfo
= vinfo
;
2314 // bcopy((const void *)boot_vinfo, (void *)&boot_video_info, sizeof(boot_video_info));
2317 * First, check if we are changing the size and/or location of the framebuffer
2319 new_vinfo
.v_name
[0] = 0;
2320 new_vinfo
.v_width
= (unsigned int)boot_vinfo
->v_width
;
2321 new_vinfo
.v_height
= (unsigned int)boot_vinfo
->v_height
;
2322 new_vinfo
.v_depth
= (unsigned int)boot_vinfo
->v_depth
;
2323 new_vinfo
.v_rowbytes
= (unsigned int)boot_vinfo
->v_rowBytes
;
2324 new_vinfo
.v_physaddr
= boot_vinfo
->v_baseAddr
; /* Get the physical address */
2325 #if defined(__i386__) || defined(__x86_64__)
2326 new_vinfo
.v_type
= (unsigned int)boot_vinfo
->v_display
;
2328 new_vinfo
.v_type
= 0;
2331 if (!lastVideoMapped
)
2332 kprintf("initialize_screen: b=%08lX, w=%08X, h=%08X, r=%08X, d=%08X\n", /* (BRINGUP) */
2333 new_vinfo
.v_physaddr
, new_vinfo
.v_width
, new_vinfo
.v_height
, new_vinfo
.v_rowbytes
, new_vinfo
.v_type
); /* (BRINGUP) */
2335 if (!new_vinfo
.v_physaddr
) /* Check to see if we have a framebuffer */
2337 kprintf("initialize_screen: No video - forcing serial mode\n"); /* (BRINGUP) */
2338 new_vinfo
.v_depth
= 0; /* vc routines are nop */
2339 (void)switch_to_serial_console(); /* Switch into serial mode */
2340 gc_graphics_boot
= FALSE
; /* Say we are not in graphics mode */
2341 disableConsoleOutput
= FALSE
; /* Allow printfs to happen */
2347 * Note that for the first time only, boot_vinfo->v_baseAddr is physical.
2350 if (kernel_map
!= VM_MAP_NULL
) /* If VM is up, we are given a virtual address */
2352 fbppage
= pmap_find_phys(kernel_pmap
, (addr64_t
)boot_vinfo
->v_baseAddr
); /* Get the physical address of frame buffer */
2353 if(!fbppage
) /* Did we find it? */
2355 panic("initialize_screen: Strange framebuffer - addr = %08X\n", (uint32_t)boot_vinfo
->v_baseAddr
);
2357 new_vinfo
.v_physaddr
= (fbppage
<< 12) | (boot_vinfo
->v_baseAddr
& PAGE_MASK
); /* Get the physical address */
2360 if (boot_vinfo
->v_length
!= 0)
2361 fbsize
= (unsigned int) round_page(boot_vinfo
->v_length
);
2363 fbsize
= (unsigned int) round_page(new_vinfo
.v_height
* new_vinfo
.v_rowbytes
); /* Remember size */
2366 if ((lastVideoPhys
!= new_vinfo
.v_physaddr
) || (fbsize
> lastVideoSize
)) /* Did framebuffer change location or get bigger? */
2368 unsigned int flags
= VM_WIMG_IO
;
2369 newVideoVirt
= io_map_spec((vm_offset_t
)new_vinfo
.v_physaddr
, fbsize
, flags
); /* Allocate address space for framebuffer */
2373 if (newVideoVirt
!= 0)
2374 new_vinfo
.v_baseaddr
= newVideoVirt
+ boot_vinfo
->v_offset
; /* Set the new framebuffer address */
2376 new_vinfo
.v_baseaddr
= lastVideoVirt
+ boot_vinfo
->v_offset
; /* Set the new framebuffer address */
2378 #if defined(__x86_64__)
2379 // Adjust the video buffer pointer to point to where it is in high virtual (above the hole)
2380 new_vinfo
.v_baseaddr
|= VM_MIN_KERNEL_ADDRESS
;
2383 /* Update the vinfo structure atomically with respect to the vc_progress task if running */
2386 simple_lock(&vc_progress_lock
);
2388 simple_unlock(&vc_progress_lock
);
2395 // If we changed the virtual address, remove the old mapping
2396 if (newVideoVirt
!= 0)
2398 if (lastVideoVirt
) /* Was the framebuffer mapped before? */
2401 if(lastVideoMapped
) /* Was this not a special pre-VM mapping? */
2404 pmap_remove(kernel_pmap
, trunc_page_64(lastVideoVirt
),
2405 round_page_64(lastVideoVirt
+ lastVideoSize
)); /* Toss mappings */
2407 if(lastVideoMapped
) /* Was this not a special pre-VM mapping? */
2409 kmem_free(kernel_map
, lastVideoVirt
, lastVideoSize
); /* Toss kernel addresses */
2412 lastVideoPhys
= (unsigned int)new_vinfo
.v_physaddr
; /* Remember the framebuffer address */
2413 lastVideoSize
= fbsize
; /* Remember the size */
2414 lastVideoVirt
= newVideoVirt
; /* Remember the virtual framebuffer address */
2415 lastVideoMapped
= (NULL
!= kernel_map
);
2419 // Graphics mode setup by the booter.
2421 gc_ops
.initialize
= vc_initialize
;
2422 gc_ops
.enable
= vc_enable
;
2423 gc_ops
.paint_char
= vc_paint_char
;
2424 gc_ops
.scroll_down
= vc_scroll_down
;
2425 gc_ops
.scroll_up
= vc_scroll_up
;
2426 gc_ops
.clear_screen
= vc_clear_screen
;
2427 gc_ops
.hide_cursor
= vc_reverse_cursor
;
2428 gc_ops
.show_cursor
= vc_reverse_cursor
;
2429 gc_ops
.update_color
= vc_update_color
;
2432 gc_initialize(&vinfo
);
2434 #ifdef GRATEFULDEBUGGER
2435 GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re-initialize GratefulDeb */
2436 #endif /* GRATEFULDEBUGGER */
2441 case kPEGraphicsMode
:
2442 panicDialogDesired
= TRUE
;
2443 gc_graphics_boot
= TRUE
;
2444 gc_desire_text
= FALSE
;
2448 panicDialogDesired
= FALSE
;
2449 disable_debug_output
= FALSE
;
2450 gc_graphics_boot
= FALSE
;
2453 case kPEAcquireScreen
:
2454 if ( gc_acquired
) break;
2455 graphics_now
= gc_graphics_boot
&& !gc_desire_text
;
2456 vc_progress_set( graphics_now
, kProgressAcquireDelay
);
2457 gc_enable( !graphics_now
);
2459 gc_desire_text
= FALSE
;
2462 case kPEEnableScreen
:
2467 if ( console_is_serial() ) break;
2469 panicDialogDesired
= FALSE
;
2470 disable_debug_output
= FALSE
;
2471 if ( gc_acquired
== FALSE
)
2473 gc_desire_text
= TRUE
;
2476 if ( gc_graphics_boot
== FALSE
) break;
2478 vc_progress_set( FALSE
, 0 );
2479 #if !CONFIG_EMBEDDED
2480 vc_enable_progressmeter( FALSE
);
2485 case kPEDisableScreen
:
2489 case kPEReleaseScreen
:
2490 gc_acquired
= FALSE
;
2491 gc_desire_text
= FALSE
;
2493 vc_progress_set( FALSE
, 0 );
2494 #if !CONFIG_EMBEDDED
2495 vc_enable_progressmeter( FALSE
);
2499 #ifdef GRATEFULDEBUGGER
2500 GratefulDebInit(0); /* Stop grateful debugger */
2501 #endif /* GRATEFULDEBUGGER */
2504 #ifdef GRATEFULDEBUGGER
2505 if ( boot_vinfo
) GratefulDebInit((bootBumbleC
*)boot_vinfo
); /* Re initialize GratefulDeb */
2506 #endif /* GRATEFULDEBUGGER */
2512 unsigned int *p
, *endp
, *row
;
2513 int col
, rowline
, rowlongs
;
2514 register unsigned int mask
;
2519 if ( vinfo
.v_depth
== 32 )
2521 else if ( vinfo
.v_depth
== 30 )
2522 mask
= (0x1ff<<20) | (0x1ff<<10) | 0x1ff;
2523 else if ( vinfo
.v_depth
== 16 )
2528 rowline
= (int)(vinfo
.v_rowscanbytes
/ 4);
2529 rowlongs
= (int)(vinfo
.v_rowbytes
/ 4);
2531 p
= (unsigned int*) vinfo
.v_baseaddr
;
2532 endp
= p
+ (rowlongs
* vinfo
.v_height
);
2534 for (row
= p
; row
< endp
; row
+= rowlongs
) {
2535 for (p
= &row
[0], col
= 0; col
< rowline
; col
++) {
2536 *p
= (*p
>> 1) & mask
;
2542 void vcattach(void); /* XXX gcc 4 warning cleanup */
2547 vm_initialized
= TRUE
;
2549 if ( gc_graphics_boot
== FALSE
)
2555 initialize_screen(NULL
, kPEReleaseScreen
);
2558 initialize_screen(NULL
, kPEAcquireScreen
);
2560 for ( index
= 0 ; index
< msgbufp
->msg_bufx
; index
++ )
2562 vcputc( 0, 0, msgbufp
->msg_bufc
[index
] );
2564 if ( msgbufp
->msg_bufc
[index
] == '\n' )
2566 vcputc( 0, 0,'\r' );
2572 #if !CONFIG_EMBEDDED
2574 int vc_progress_meter_enable
;
2575 int vc_progress_meter_value
;
2577 static void * vc_progress_meter_backbuffer
;
2578 static int vc_progress_meter_drawn
;
2581 vc_draw_progress_meter(int select
, unsigned int flags
, int x1
, int x2
)
2583 const unsigned char * data
;
2587 ox
= ((vinfo
.v_width
- kProgressBarWidth
) / 2);
2588 oy
= vinfo
.v_height
- (((vinfo
.v_height
/ 2) - vc_progress
->dy
+ kProgressBarHeight
) / 2);
2590 if (kDataBack
== flags
)
2592 // restore back bits
2593 vc_blit_rect(ox
+ x1
, oy
, x1
,
2594 x2
, kProgressBarHeight
, 0, kProgressBarWidth
,
2595 NULL
, vc_progress_meter_backbuffer
, flags
);
2599 for (x
= x1
; x
< x2
; x
+= w
)
2601 if (x
< kProgressBarCapWidth
)
2603 if (x2
< kProgressBarCapWidth
)
2606 w
= kProgressBarCapWidth
- x
;
2607 data
= &progressmeter_leftcap
[select
& 1][0];
2609 vc_blit_rect(ox
+ x
, oy
, x
,
2610 w
, kProgressBarHeight
, kProgressBarCapWidth
, kProgressBarWidth
,
2611 data
, vc_progress_meter_backbuffer
, flags
);
2613 else if (x
< (kProgressBarWidth
- kProgressBarCapWidth
))
2615 if (x2
< (kProgressBarWidth
- kProgressBarCapWidth
))
2618 w
= (kProgressBarWidth
- kProgressBarCapWidth
) - x
;
2619 data
= &progressmeter_middle
[select
& 1][0];
2620 vc_blit_rect(ox
+ x
, oy
, x
,
2621 w
, kProgressBarHeight
, 1, kProgressBarWidth
,
2622 data
, vc_progress_meter_backbuffer
, flags
);
2627 data
= &progressmeter_rightcap
[select
& 1][0];
2628 data
+= x
- (kProgressBarWidth
- kProgressBarCapWidth
);
2629 vc_blit_rect(ox
+ x
, oy
, x
,
2630 w
, kProgressBarHeight
, kProgressBarCapWidth
, kProgressBarWidth
,
2631 data
, vc_progress_meter_backbuffer
, flags
);
2637 vc_enable_progressmeter(int new_value
)
2640 void * new_buffer
= NULL
;
2643 new_buffer
= kalloc(kProgressBarWidth
* kProgressBarHeight
* sizeof(int));
2646 simple_lock(&vc_progress_lock
);
2648 if (gc_enabled
|| !gc_acquired
|| !gc_graphics_boot
)
2651 if (new_value
!= vc_progress_meter_enable
)
2655 vc_progress_meter_backbuffer
= new_buffer
;
2656 vc_draw_progress_meter(FALSE
, kDataAlpha
| kSave
, 0, kProgressBarWidth
);
2657 vc_progress_meter_enable
= TRUE
;
2659 vc_progress_meter_drawn
= 0;
2661 else if (vc_progress_meter_backbuffer
)
2663 vc_draw_progress_meter(0, kDataBack
, 0, kProgressBarWidth
);
2664 new_buffer
= vc_progress_meter_backbuffer
;
2665 vc_progress_meter_backbuffer
= NULL
;
2666 vc_progress_meter_enable
= FALSE
;
2671 simple_unlock(&vc_progress_lock
);
2675 kfree(new_buffer
, kProgressBarWidth
* kProgressBarHeight
* sizeof(int));
2679 vc_set_progressmeter(int new_value
)
2684 if ((new_value
< 0) | (new_value
> 100))
2688 simple_lock(&vc_progress_lock
);
2690 if (vc_progress_meter_enable
)
2692 vc_progress_meter_value
= new_value
;
2693 x2
= ((kProgressBarWidth
- 1) * new_value
) / 100;
2694 if (x2
> vc_progress_meter_drawn
)
2695 vc_draw_progress_meter(TRUE
, kDataAlpha
, vc_progress_meter_drawn
, x2
);
2697 vc_draw_progress_meter(FALSE
, kDataAlpha
, x2
, vc_progress_meter_drawn
);
2698 vc_progress_meter_drawn
= x2
;
2701 simple_unlock(&vc_progress_lock
);
2705 #endif /* !CONFIG_EMBEDDED */