[OpenBIOS] [PATCH 13/20] video_common.c: move colour palette code into individual devices
Mark Cave-Ayland
mark.cave-ayland at ilande.co.uk
Sat Jun 15 10:38:51 CEST 2013
Instead if having a large #ifdef .. #endif section in video_set_color(), move
the device-specific hardware setters into each display device package.
To do this, we keep track of the display ihandle in the video structure and
use it to invoke the low-level hardware setter routine (and optional palette
refresh) if required.
Also since the display-ih isn't called until is-install, defer the colour
palette initialisation from init_video() to is-install.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
openbios-devel/arch/sparc32/console.c | 17 ++++++++++
openbios-devel/drivers/sbus.c | 1 +
openbios-devel/drivers/vga_vbe.c | 18 +++++++++++
openbios-devel/forth/device/display.fs | 25 +++++++++++++++
openbios-devel/include/drivers/drivers.h | 1 +
openbios-devel/include/libopenbios/video.h | 1 +
openbios-devel/libopenbios/video_common.c | 46 ++++++++++++++--------------
openbios-devel/packages/molvideo.c | 19 +++++++++---
8 files changed, 101 insertions(+), 27 deletions(-)
diff --git a/openbios-devel/arch/sparc32/console.c b/openbios-devel/arch/sparc32/console.c
index c986e2b..53aa77f 100644
--- a/openbios-devel/arch/sparc32/console.c
+++ b/openbios-devel/arch/sparc32/console.c
@@ -11,6 +11,7 @@
#include "openbios.h"
#include "libopenbios/console.h"
#include "libopenbios/ofmem.h"
+#include "libopenbios/video.h"
void cls(void);
@@ -41,6 +42,22 @@ void tcx_init(uint64_t base)
dac = (uint32_t *)ofmem_map_io(base + DAC_BASE, DAC_SIZE);
}
+/* ( r g b index -- ) */
+void tcx_hw_set_color(void)
+{
+ int index = POP();
+ int b = POP();
+ int g = POP();
+ int r = POP();
+
+ if( VIDEO_DICT_VALUE(video.depth) == 8 ) {
+ dac[0] = index << 24;
+ dac[1] = r << 24; // Red
+ dac[1] = g << 24; // Green
+ dac[1] = b << 24; // Blue
+ }
+}
+
#endif
/* ******************************************************************
diff --git a/openbios-devel/drivers/sbus.c b/openbios-devel/drivers/sbus.c
index d171018..fbac2d7 100644
--- a/openbios-devel/drivers/sbus.c
+++ b/openbios-devel/drivers/sbus.c
@@ -329,6 +329,7 @@ ob_tcx_init(unsigned int slot, const char *path)
fword("property");
}
+ bind_func("hw-set-color", tcx_hw_set_color);
feval("['] qemu-tcx-driver-init is-install");
chosen = find_dev("/chosen");
diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c
index 884c261..33765b6 100644
--- a/openbios-devel/drivers/vga_vbe.c
+++ b/openbios-devel/drivers/vga_vbe.c
@@ -103,6 +103,22 @@ void vga_vbe_set_mode(int width, int height, int depth)
vga_build_rgb_palette();
}
+/* Low-level Forth accessor to update VGA color registers */
+
+/* ( r g b index -- ) */
+static
+void vga_hw_set_color(void)
+{
+ int index = POP();
+ int b = POP();
+ int g = POP();
+ int r = POP();
+
+ vga_set_color(index, (r & 0xff),
+ (g & 0xff),
+ (b & 0xff));
+}
+
void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size,
unsigned long rom, uint32_t rom_size)
{
@@ -128,6 +144,8 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size,
ph = get_cur_dev();
#endif
+ bind_func("hw-set-color", vga_hw_set_color);
+
set_int_property(ph, "width", VIDEO_DICT_VALUE(video.w));
set_int_property(ph, "height", VIDEO_DICT_VALUE(video.h));
set_int_property(ph, "depth", VIDEO_DICT_VALUE(video.depth));
diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs
index cf709fa..ae7bdeb 100644
--- a/openbios-devel/forth/device/display.fs
+++ b/openbios-devel/forth/device/display.fs
@@ -48,6 +48,7 @@ create color-palette 100 cells allot
2 value font-spacing
0 value depth-bits
0 value line-bytes
+0 value display-ih
\ internal values read from QEMU firmware interface
0 value qemu-video-addr
@@ -353,6 +354,8 @@ defer fb8-invertrect
0 to inverse?
0 to inverse-screen?
+ my-self to display-ih
+
\ set defer functions to 8bit versions
['] fb8-draw-character to draw-character
@@ -375,6 +378,28 @@ defer fb8-invertrect
then
to foreground-color to background-color
+ \ setup palette
+ 10101 ['] color-palette cell+ ff 0 do
+ dup 2 pick i * swap ! cell+
+ loop 2drop
+
+ \ special background color
+ ffffcc ['] color-palette cell+ fe cells + !
+
+ \ load palette onto the hardware
+ ['] color-palette cell+ ff 0 do
+ dup @ ff0000 and d# 16 rshift
+ 1 pick @ ff00 and d# 8 rshift
+ 2 pick @ ff and
+ i
+ s" hw-set-color" $find if
+ execute
+ else
+ 2drop
+ then
+ cell+
+ loop drop
+
\ ... but let's override with some better defaults
fe to background-color
0 to foreground-color
diff --git a/openbios-devel/include/drivers/drivers.h b/openbios-devel/include/drivers/drivers.h
index d139ace..d041e81 100644
--- a/openbios-devel/include/drivers/drivers.h
+++ b/openbios-devel/include/drivers/drivers.h
@@ -47,6 +47,7 @@ int ob_sbus_init(uint64_t base, int machine_id);
/* arch/sparc32/console.c */
void tcx_init(uint64_t base);
+void tcx_hw_set_color(void);
void kbd_init(uint64_t base);
#endif
#ifdef CONFIG_DRIVER_IDE
diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h
index bcd024e..cf2b5db 100644
--- a/openbios-devel/include/libopenbios/video.h
+++ b/openbios-devel/include/libopenbios/video.h
@@ -30,6 +30,7 @@ void video_fill_rect(void);
extern struct video_info {
int has_video;
+ volatile ihandle_t *ih;
volatile phys_addr_t mphys;
volatile ucell *mvirt;
volatile ucell *rb, *w, *h, *depth;
diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c
index 9d45e69..ca2826e 100644
--- a/openbios-devel/libopenbios/video_common.c
+++ b/openbios-devel/libopenbios/video_common.c
@@ -46,27 +46,30 @@ video_get_color( int col_ind )
void
video_set_color( int ind, unsigned long color )
{
+ xt_t hw_xt = 0;
+
if( !video.has_video || ind < 0 || ind > 255 )
return;
video.pal[ind] = color;
-#ifdef CONFIG_MOL
- if( VIDEO_DICT_VALUE(video.depth) == 8 )
- OSI_SetColor( ind, color );
-#elif defined(CONFIG_SPARC32)
-#if defined(CONFIG_DEBUG_CONSOLE_VIDEO)
- if( VIDEO_DICT_VALUE(video.depth) == 8 ) {
- dac[0] = ind << 24;
- dac[1] = ((color >> 16) & 0xff) << 24; // Red
- dac[1] = ((color >> 8) & 0xff) << 24; // Green
- dac[1] = (color & 0xff) << 24; // Blue
- }
-#endif
-#else
- vga_set_color(ind, ((color >> 16) & 0xff),
- ((color >> 8) & 0xff),
- (color & 0xff));
-#endif
+ /* Call the low-level hardware setter in the
+ display package */
+ hw_xt = find_ih_method("hw-set-color", VIDEO_DICT_VALUE(video.ih));
+ if (hw_xt) {
+ PUSH((color >> 16) & 0xff); // Red
+ PUSH((color >> 8) & 0xff); // Green
+ PUSH(color & 0xff); // Blue
+ PUSH(ind);
+ PUSH(hw_xt);
+ fword("execute");
+ }
+
+ /* Call the low-level palette update if required */
+ hw_xt = find_ih_method("hw-refresh-palette", VIDEO_DICT_VALUE(video.ih));
+ if (hw_xt) {
+ PUSH(hw_xt);
+ fword("execute");
+ }
}
/* ( fbaddr maskaddr width height fgcolor bgcolor -- ) */
@@ -219,6 +222,9 @@ void setup_video(phys_addr_t phys, ucell virt)
video.mphys = phys;
+ feval("['] display-ih cell+");
+ video.ih = cell2pointer(POP());
+
feval("['] qemu-video-addr cell+");
video.mvirt = cell2pointer(POP());
feval("['] qemu-video-width cell+");
@@ -277,7 +283,6 @@ void setup_video(phys_addr_t phys, ucell virt)
void
init_video(void)
{
- int i;
#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI)
int size;
#endif
@@ -306,9 +311,4 @@ init_video(void)
ofmem_claim_virt( VIDEO_DICT_VALUE(video.mvirt), size, 0 );
ofmem_map( video.mphys, VIDEO_DICT_VALUE(video.mvirt), size, ofmem_arch_io_translation_mode(video.mphys) );
#endif
-
- for( i=0; i<256; i++ )
- video_set_color( i, i * 0x010101 );
-
- video_set_color( 254, 0xffffcc );
}
diff --git a/openbios-devel/packages/molvideo.c b/openbios-devel/packages/molvideo.c
index 742f516..24cc2fd 100644
--- a/openbios-devel/packages/molvideo.c
+++ b/openbios-devel/packages/molvideo.c
@@ -31,15 +31,24 @@
DECLARE_NODE( video, 0, 0, "Tdisplay" );
+#ifdef CONFIG_MOL
static void
molvideo_refresh_palette( void )
{
-#ifdef CONFIG_MOL
+
if( VIDEO_DICT_VALUE(video.depth) == 8 )
OSI_RefreshPalette();
-#endif
}
+static void
+molvideo_hw_set_color( void )
+{
+
+ if( VIDEO_DICT_VALUE(video.depth) == 8 )
+ OSI_SetColor( ind, color );
+}
+#endif
+
/* ( -- width height ) (?) */
static void
molvideo_dimensions( void )
@@ -61,7 +70,6 @@ molvideo_set_colors( void )
unsigned long col = (p[0] << 16) | (p[1] << 8) | p[2];
video_set_color( i + start, col );
}
- molvideo_refresh_palette();
}
/* ( r g b index -- ) */
@@ -75,7 +83,6 @@ molvideo_color_bang( void )
unsigned long col = ((r << 16) & 0xff0000) | ((g << 8) & 0x00ff00) | (b & 0xff);
/* printk("color!: %08lx %08lx %08lx %08lx\n", r, g, b, index ); */
video_set_color( index, col );
- molvideo_refresh_palette();
}
/* ( color_ind x y width height -- ) (?) */
@@ -143,6 +150,10 @@ molvideo_startup_splash( void )
NODE_METHODS( video ) = {
+#ifdef CONFIG_MOL
+ {"hw-set-color", molvideo_hw_set_color },
+ {"hw-refresh-palette", molvideo_refresh_palette},
+#endif
{"dimensions", molvideo_dimensions },
{"set-colors", molvideo_set_colors },
{"fill-rectangle", molvideo_fill_rect },
--
1.7.10.4
More information about the OpenBIOS
mailing list