This should be the final in the display rework patch series which completes the conversion of the VGA/TCX drivers from Forth to C. The series also includes several other improvements:
- Fixes for SPARC32 romvec stdin/stdout initialisation - Fixes for ioc!/iow!/iol! words - Implementation of SBus and PCI map functions (see comments for PCI) - Isolation of all remaining MOL code into molvideo.h - Simple implementation of TCX "probe" function (will morph into probe-self with very little work) - Removal of remaining hacks required to support a mixed C/Forth display environment
Once this patchset is applied, it only remains to implement cpeek and augment the SBus probe-self function to provide the ability to execute FCode ROMs supplied by QEMU.
Mark Cave-Ayland (14): forth.c: fix ioc!, iow! and iol! words vga: move VGA initialisation from C to Forth video: move all non MOL-specific code from molvideo.c to vga.fs pci/vga: move PCI framebuffer map functions info Forth vga: move initialisation of screen-#columns/screen-#rows to setup_video() SPARC32: fix romvec stdin/stdout field initialisation display: move creation of "display" and "screen" properties to Forth sbus: implement map-in and map-out words sbus/tcx: implement probe_self() wrapper tcx.fs: tidy-up lookups using (find-xt) and use openbios-* vars where appropriate tcx.fs: move DAC programming from C to tcx.fs tcx.fs: move framebuffer mapping over from C to tcx.fs video: remove video_set_color() vga: remove vga_vbe_init() and vga_vbe.c
openbios-devel/arch/ppc/qemu/init.c | 18 --- openbios-devel/arch/sparc32/console.c | 38 ----- openbios-devel/arch/sparc32/openbios.c | 19 +-- openbios-devel/arch/sparc32/romvec.c | 14 +- openbios-devel/arch/sparc32/tree.fs | 21 +-- openbios-devel/arch/sparc64/openbios.c | 18 --- openbios-devel/drivers/build.xml | 1 - openbios-devel/drivers/iommu.c | 32 ++++ openbios-devel/drivers/pci.c | 96 ++++++++--- openbios-devel/drivers/pci.fs | 77 +++++++++ openbios-devel/drivers/sbus.c | 238 ++++------------------------ openbios-devel/drivers/sbus.fs | 60 +++++++ openbios-devel/drivers/tcx.fs | 217 +++++++++++++++++++++++-- openbios-devel/drivers/vga.fs | 192 +++++++++++++++++++--- openbios-devel/drivers/vga_vbe.c | 191 ---------------------- openbios-devel/forth/admin/iocontrol.fs | 16 ++ openbios-devel/forth/device/display.fs | 13 +- openbios-devel/include/drivers/drivers.h | 2 - openbios-devel/include/libopenbios/video.h | 4 +- openbios-devel/kernel/forth.c | 6 +- openbios-devel/libopenbios/video_common.c | 46 ++---- openbios-devel/packages/build.xml | 2 +- openbios-devel/packages/molvideo.c | 78 ++------- 23 files changed, 718 insertions(+), 681 deletions(-) delete mode 100644 openbios-devel/drivers/vga_vbe.c
The kernel implementation for the above words is incorrect because the value/reg parameters are the wrong way around.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/kernel/forth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/openbios-devel/kernel/forth.c b/openbios-devel/kernel/forth.c index 0d3b2d2..61dd70d 100644 --- a/openbios-devel/kernel/forth.c +++ b/openbios-devel/kernel/forth.c @@ -1787,7 +1787,7 @@ static void iocstore(void) cell reg = POP(); cell val = POP();
- outb(reg, val); + outb(val, reg); #else (void)POP(); (void)POP(); @@ -1805,7 +1805,7 @@ static void iowstore(void) cell reg = POP(); cell val = POP();
- outw(reg, val); + outw(val, reg); #else (void)POP(); (void)POP(); @@ -1823,7 +1823,7 @@ static void iolstore(void) ucell reg = POP(); ucell val = POP();
- outl(reg, val); + outl(val, reg); #else (void)POP(); (void)POP();
This includes the low-level VGA register accesses and also the package properties.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/vga.fs | 137 ++++++++++++++++++++++++++++++++++---- openbios-devel/drivers/vga_vbe.c | 79 ---------------------- 2 files changed, 124 insertions(+), 92 deletions(-)
diff --git a/openbios-devel/drivers/vga.fs b/openbios-devel/drivers/vga.fs index 538af57..d3fe95c 100644 --- a/openbios-devel/drivers/vga.fs +++ b/openbios-devel/drivers/vga.fs @@ -8,36 +8,147 @@ fcode-version3
\ -\ Instead of using fixed values for the framebuffer address and the width -\ and height, grab the ones passed in by QEMU/generated by OpenBIOS +\ Dictionary lookups for words that don't have an FCode \
-: openbios-video-addr - " openbios-video-addr" $find if - cell+ @ +: (find-xt) \ ( str len -- xt | -1 ) + $find if + exit + else + -1 then ;
-: openbios-video-width - " openbios-video-width" $find if - cell+ @ - then +" openbios-video-addr" (find-xt) cell+ value openbios-video-addr-xt +" openbios-video-width" (find-xt) cell+ value openbios-video-width-xt +" openbios-video-height" (find-xt) cell+ value openbios-video-height-xt +" depth-bits" (find-xt) cell+ value depth-bits-xt +" line-bytes" (find-xt) cell+ value line-bytes-xt + +: openbios-video-addr openbios-video-addr-xt @ ; +: openbios-video-width openbios-video-width-xt @ ; +: openbios-video-height openbios-video-height-xt @ ; +: depth-bits depth-bits-xt @ ; +: line-bytes line-bytes-xt @ ; + +\ +\ IO port words +\ + +" ioc!" (find-xt) value ioc!-xt +" iow!" (find-xt) value iow!-xt + +: ioc! ioc!-xt execute ; +: iow! iow!-xt execute ; + +\ +\ VGA registers +\ + +h# 3c0 constant vga-addr +h# 3c8 constant dac-write-addr +h# 3c9 constant dac-data-addr + +: vga-color! ( r g b index -- ) + \ Set the VGA colour registers + dac-write-addr ioc! rot + 2 >> dac-data-addr ioc! swap + 2 >> dac-data-addr ioc! + 2 >> dac-data-addr ioc! ;
-: openbios-video-height - " openbios-video-height" $find if - cell+ @ - then +\ +\ VBE registers +\ + +h# 0 constant VBE_DISPI_INDEX_ID +h# 1 constant VBE_DISPI_INDEX_XRES +h# 2 constant VBE_DISPI_INDEX_YRES +h# 3 constant VBE_DISPI_INDEX_BPP +h# 4 constant VBE_DISPI_INDEX_ENABLE +h# 5 constant VBE_DISPI_INDEX_BANK +h# 6 constant VBE_DISPI_INDEX_VIRT_WIDTH +h# 7 constant VBE_DISPI_INDEX_VIRT_HEIGHT +h# 8 constant VBE_DISPI_INDEX_X_OFFSET +h# 9 constant VBE_DISPI_INDEX_Y_OFFSET +h# a constant VBE_DISPI_INDEX_NB + +h# 0 constant VBE_DISPI_DISABLED +h# 1 constant VBE_DISPI_ENABLED + +\ +\ Bochs VBE register writes +\ + +: vbe-iow! ( val addr -- ) + h# 1ce iow! + h# 1d0 iow! ;
+\ +\ Initialise Bochs VBE mode +\ + +: vbe-init ( -- ) + h# 0 vga-addr ioc! \ Enable blanking + VBE_DISPI_DISABLED VBE_DISPI_INDEX_ENABLE vbe-iow! + h# 0 VBE_DISPI_INDEX_X_OFFSET vbe-iow! + h# 0 VBE_DISPI_INDEX_Y_OFFSET vbe-iow! + openbios-video-width VBE_DISPI_INDEX_XRES vbe-iow! + openbios-video-height VBE_DISPI_INDEX_YRES vbe-iow! + depth-bits VBE_DISPI_INDEX_BPP vbe-iow! + VBE_DISPI_ENABLED VBE_DISPI_INDEX_ENABLE vbe-iow! + h# 0 vga-addr ioc! + h# 20 vga-addr ioc! \ Disable blanking +; + +\ +\ Publically visible words +\ + +external + +[IFDEF] CONFIG_MOL +defer mol-color! + +\ Hook for MOL (see packages/molvideo.c) + +: hw-set-color ( r g b index -- ) + mol-color! +; + +[ELSE] + +\ Standard VGA + +: hw-set-color ( r g b index -- ) + vga-color! +; + +[THEN] + +headerless + +\ +\ Installation +\ + : qemu-vga-driver-install ( -- ) openbios-video-addr to frame-buffer-adr default-font set-font + + frame-buffer-adr encode-int " address" property + openbios-video-width encode-int " width" property + openbios-video-height encode-int " height" property + depth-bits encode-int " depth" property + line-bytes encode-int " linebytes" property + openbios-video-width openbios-video-height over char-width / over char-height / fb8-install ;
: qemu-vga-driver-init + vbe-init ['] qemu-vga-driver-install is-install ;
diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 75b232e..54d9fb1 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -51,74 +51,6 @@ #define VBE_DISPI_LFB_ENABLED 0x40 #define VBE_DISPI_NOCLEARMEM 0x80
-static void vbe_outw(int index, int val) -{ - outw(index, 0x1ce); - outw(val, 0x1d0); -} - -/* for depth = 8 mode, set a hardware palette entry */ -void vga_set_color(int i, unsigned int r, unsigned int g, unsigned int b) -{ - r &= 0xff; - g &= 0xff; - b &= 0xff; - outb(i, 0x3c8); - outb(r >> 2, 0x3c9); - outb(g >> 2, 0x3c9); - outb(b >> 2, 0x3c9); -} - -/* build standard RGB palette */ -static void vga_build_rgb_palette(void) -{ - static const uint8_t pal_value[6] = { 0x00, 0x33, 0x66, 0x99, 0xcc, 0xff }; - int i, r, g, b; - - i = 0; - for(r = 0; r < 6; r++) { - for(g = 0; g < 6; g++) { - for(b = 0; b < 6; b++) { - vga_set_color(i, pal_value[r], pal_value[g], pal_value[b]); - i++; - } - } - } -} - -/* depth = 8, 15, 16 or 32 */ -void vga_vbe_set_mode(int width, int height, int depth) -{ - outb(0x00, 0x3c0); /* enable blanking */ - vbe_outw(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED); - vbe_outw(VBE_DISPI_INDEX_X_OFFSET, 0); - vbe_outw(VBE_DISPI_INDEX_Y_OFFSET, 0); - vbe_outw(VBE_DISPI_INDEX_XRES, width); - vbe_outw(VBE_DISPI_INDEX_YRES, height); - vbe_outw(VBE_DISPI_INDEX_BPP, depth); - vbe_outw(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED); - outb(0x00, 0x3c0); - outb(0x20, 0x3c0); /* disable blanking */ - - if (depth == 8) - 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) @@ -136,9 +68,6 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, #endif
setup_video(phys, fb); - vga_vbe_set_mode(VIDEO_DICT_VALUE(video.w), - VIDEO_DICT_VALUE(video.h), - VIDEO_DICT_VALUE(video.depth));
#if 0 ph = find_dev(path); @@ -146,14 +75,6 @@ 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)); - set_int_property(ph, "linebytes", VIDEO_DICT_VALUE(video.rb)); - set_int_property(ph, "address", (u32)(fb & ~0x0000000F)); - molvideo_init();
chosen = find_dev("/chosen");
This now leaves just the MOL code in packages/molvideo.c and so now we no longer have a mixture of MOL and non-MOL methods in this packages. As a result of this, we can now conditionally build molvideo.c only if CONFIG_MOL is defined.
(Note: I have no way of testing this as I gather that OpenBIOS was pulled from MOL due to compatibility issues at some point in the past. Perhaps one day someone will try and update and see what happens?)
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/pci.c | 7 +++ openbios-devel/drivers/vga.fs | 31 +++++++++++++ openbios-devel/drivers/vga_vbe.c | 3 -- openbios-devel/forth/device/display.fs | 2 +- openbios-devel/packages/build.xml | 2 +- openbios-devel/packages/molvideo.c | 78 ++++++-------------------------- 6 files changed, 55 insertions(+), 68 deletions(-)
diff --git a/openbios-devel/drivers/pci.c b/openbios-devel/drivers/pci.c index 1b4628e..3f37fd8 100644 --- a/openbios-devel/drivers/pci.c +++ b/openbios-devel/drivers/pci.c @@ -24,6 +24,7 @@
#include "drivers/drivers.h" #include "drivers/vga.h" +#include "packages/video.h" #include "timer.h" #include "pci.h" #include "pci_database.h" @@ -773,6 +774,12 @@ int vga_config_cb (const pci_config_t *config)
/* Currently we don't read FCode from the hardware but execute it directly */ feval("['] vga-driver-fcode 2 cells + 1 byte-load"); + +#ifdef CONFIG_MOL + /* Install special words for Mac On Linux */ + molvideo_init(); +#endif + }
return 0; diff --git a/openbios-devel/drivers/vga.fs b/openbios-devel/drivers/vga.fs index d3fe95c..43c8819 100644 --- a/openbios-devel/drivers/vga.fs +++ b/openbios-devel/drivers/vga.fs @@ -31,6 +31,9 @@ fcode-version3 : depth-bits depth-bits-xt @ ; : line-bytes line-bytes-xt @ ;
+" fb8-fillrect" (find-xt) value fb8-fillrect-xt +: fb8-fillrect fb8-fillrect-xt execute ; + \ \ IO port words \ @@ -112,6 +115,9 @@ external defer mol-color!
\ Hook for MOL (see packages/molvideo.c) +\ +\ Perhaps for neatness this there should be a separate molvga.fs +\ but let's leave it here for now.
: hw-set-color ( r g b index -- ) mol-color! @@ -127,6 +133,31 @@ defer mol-color!
[THEN]
+: color! ( r g b index -- ) + hw-set-color +; + +: fill-rectangle ( color_ind x y width height -- ) + fb8-fillrect +; + +: dimensions ( -- width height ) + openbios-video-width + openbios-video-height +; + +: set-colors ( table start count -- ) + 0 do + over dup \ ( table start table table ) + c@ swap 1+ \ ( table start r table-g ) + dup c@ swap 1+ \ ( table start r g table-b ) + c@ 3 pick \ ( table start r g b index ) + hw-set-color \ ( table start ) + 1+ + swap 3 + swap \ ( table+3 start+1 ) + loop +; + headerless
\ diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 54d9fb1..8c224d6 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -27,7 +27,6 @@ #include "drivers/vga.h" #include "libopenbios/video.h" #include "libopenbios/ofmem.h" -#include "packages/video.h"
/* VGA init. We use the Bochs VESA VBE extensions */ #define VBE_DISPI_INDEX_ID 0x0 @@ -75,8 +74,6 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, ph = get_cur_dev(); #endif
- molvideo_init(); - chosen = find_dev("/chosen"); push_str(path); fword("open-dev"); diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index 8c4fb45..6d77dfa 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -408,7 +408,7 @@ defer fb8-invertrect
\ If we have a startup splash then display it [IFDEF] CONFIG_MOL - startup-splash 2000 ms + mol-startup-splash 2000 ms fb8-erase-screen [THEN] ; diff --git a/openbios-devel/packages/build.xml b/openbios-devel/packages/build.xml index 0384c41..bf49099 100644 --- a/openbios-devel/packages/build.xml +++ b/openbios-devel/packages/build.xml @@ -11,7 +11,7 @@ <object source="nvram.c"/> <object source="pc-parts.c" condition="PC_PARTS"/> <object source="sun-parts.c" condition="SUN_PARTS"/> - <object source="molvideo.c"/> + <object source="molvideo.c" condition="MOL"/> <object source="xcoff-loader.c" condition="LOADER_XCOFF"/> </library>
diff --git a/openbios-devel/packages/molvideo.c b/openbios-devel/packages/molvideo.c index 9dd60b8..787c4dc 100644 --- a/openbios-devel/packages/molvideo.c +++ b/openbios-devel/packages/molvideo.c @@ -2,7 +2,7 @@ * Creation Date: <2002/10/23 20:26:40 samuel> * Time-stamp: <2004/01/07 19:39:15 samuel> * - * <video.c> + * <molvideo.c> * * Mac-on-Linux display node * @@ -30,47 +30,6 @@
DECLARE_NODE( video, 0, 0, "Tdisplay" );
-#ifdef CONFIG_MOL -static void -molvideo_refresh_palette( void ) -{ - - if( VIDEO_DICT_VALUE(video.depth) == 8 ) - OSI_RefreshPalette(); -} - -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 ) -{ - fword("screen-width"); - fword("screen-height"); -} - -/* ( table start count -- ) (?) */ -static void -molvideo_set_colors( void ) -{ - int count = POP(); - int start = POP(); - unsigned char *p = (unsigned char*)cell2pointer(POP()); - int i; - - for( i=0; i<count; i++, p+=3 ) { - unsigned long col = (p[0] << 16) | (p[1] << 8) | p[2]; - video_set_color( i + start, col ); - } -} - /* ( r g b index -- ) */ static void molvideo_color_bang( void ) @@ -81,31 +40,26 @@ molvideo_color_bang( void ) int r = POP(); 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 ); -}
-/* ( color_ind x y width height -- ) (?) */ -static void -molvideo_fill_rect ( void ) -{ - video_fill_rect(); + if( VIDEO_DICT_VALUE(video.depth) == 8 ) { + OSI_SetColor( index, col ); + OSI_RefreshPalette(); + } }
/* ( -- ) - really should be reworked as draw-logo */ static void molvideo_startup_splash( void ) { -#ifdef CONFIG_MOL int fd, s, i, y, x, dx, dy; int width, height; char *pp, *p; char buf[64]; -#endif
/* only draw logo in 24-bit mode (for now) */ if( VIDEO_DICT_VALUE(video.depth) < 15 ) return; -#ifdef CONFIG_MOL + for( i=0; i<2; i++ ) { if( !BootHGetStrResInd("bootlogo", buf, sizeof(buf), 0, i) ) return; @@ -141,23 +95,14 @@ molvideo_startup_splash( void ) } free( p ); } -#else + /* No bootlogo support yet on other platforms */ return; -#endif }
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 }, - {"color!", molvideo_color_bang }, - {"startup-splash", molvideo_startup_splash }, + {"mol-startup-splash", molvideo_startup_splash }, };
@@ -168,5 +113,12 @@ NODE_METHODS( video ) = { void molvideo_init(void) { + xt_t color_bang; + REGISTER_NODE( video ); + + /* Bind the MOL graphic routines to the mol-color! defer */ + color_bang = bind_noname_func(molvideo_color_bang); + PUSH(color_bang); + feval(" to mol-color!"); }
Here we move the code to map the PCI framebuffer into Forth. This is done by introducing a "pci-map-in" word on the /pci node to enable Forth code to perform memory-mapping as required.
This is a slight departure from the specification which requires a "map-in" word, but this is because the OpenBIOS PCI bus enumerator *always* configures BARs regardless of whether or not an FCode payload is detected. In order to avoid having to rewrite the bus enumeration code in Forth, we instead create a "pci-bar>pci-region" word which takes the BAR register as a parameter and returns the configured BAR bus address and size. This can then be passed to the "pci-map-in" word in order to do the work.
Finally with this in place, we can remove the mapping that takes place in vga_vbe_init().
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/pci.c | 56 ++++++++++++++++++++++----- openbios-devel/drivers/pci.fs | 77 ++++++++++++++++++++++++++++++++++++++ openbios-devel/drivers/vga.fs | 40 +++++++++++++++----- openbios-devel/drivers/vga_vbe.c | 8 ---- 4 files changed, 154 insertions(+), 27 deletions(-)
diff --git a/openbios-devel/drivers/pci.c b/openbios-devel/drivers/pci.c index 3f37fd8..368d7b5 100644 --- a/openbios-devel/drivers/pci.c +++ b/openbios-devel/drivers/pci.c @@ -17,6 +17,7 @@
#include "config.h" #include "libopenbios/bindings.h" +#include "libopenbios/ofmem.h" #include "kernel/kernel.h" #include "drivers/pci.h" #include "libc/byteorder.h" @@ -25,6 +26,7 @@ #include "drivers/drivers.h" #include "drivers/vga.h" #include "packages/video.h" +#include "libopenbios/video.h" #include "timer.h" #include "pci.h" #include "pci_database.h" @@ -139,6 +141,15 @@ static void dump_reg_property(const char* description, int nreg, u32 *reg) } #endif
+static unsigned long pci_bus_addr_to_host_addr(uint32_t ba) +{ +#ifdef CONFIG_SPARC64 + return arch->cfg_data + (unsigned long)ba; +#else + return (unsigned long)ba; +#endif +} + static void ob_pci_open(int *idx) { @@ -330,12 +341,48 @@ ob_pci_encode_unit(int *idx) ss, dev, fn, buf); }
+/* ( pci-addr.lo pci-addr.hi size -- virt ) */ + +static void +ob_pci_map_in(int *idx) +{ + phys_addr_t phys; + uint32_t ba; + ucell size, virt; + + PCI_DPRINTF("ob_pci_bar_map_in idx=%p\n", idx); + + size = POP(); + POP(); + ba = POP(); + + phys = pci_bus_addr_to_host_addr(ba); + +#if defined(CONFIG_OFMEM) + ofmem_claim_phys(phys, size, 0); + +#if defined(CONFIG_SPARC64) + /* Fix virtual address on SPARC64 somewhere else */ + virt = ofmem_claim_virt(0xfe000000ULL, size, 0); +#else + virt = ofmem_claim_virt(phys, size, 0); +#endif + + ofmem_map(phys, virt, size, ofmem_arch_io_translation_mode(phys)); + + PUSH(virt); +#else + PUSH(phys); +#endif +} + NODE_METHODS(ob_pci_bus_node) = { { NULL, ob_pci_initialize }, { "open", ob_pci_open }, { "close", ob_pci_close }, { "decode-unit", ob_pci_decode_unit }, { "encode-unit", ob_pci_encode_unit }, + { "pci-map-in", ob_pci_map_in }, };
NODE_METHODS(ob_pci_simple_node) = { @@ -485,15 +532,6 @@ static void pci_host_set_ranges(const pci_config_t *config) set_property(dev, "ranges", (char *)props, ncells * sizeof(props[0])); }
-static unsigned long pci_bus_addr_to_host_addr(uint32_t ba) -{ -#ifdef CONFIG_SPARC64 - return arch->cfg_data + (unsigned long)ba; -#else - return (unsigned long)ba; -#endif -} - int host_config_cb(const pci_config_t *config) { //XXX this overrides "reg" property diff --git a/openbios-devel/drivers/pci.fs b/openbios-devel/drivers/pci.fs index e8d25a0..563b652 100644 --- a/openbios-devel/drivers/pci.fs +++ b/openbios-devel/drivers/pci.fs @@ -12,4 +12,81 @@ rot encode-int encode+ ;
+\ Get region offset for BAR reg +: pci-bar-offset@ ( bar-reg -- off.lo off.hi -1 | 0 ) + " reg" active-package get-package-property 0= if + begin + decode-phys \ ( reg prop prop-len phys.lo phys.mid phys.hi ) + ff and 5 pick = if + >r >r 3drop r> r> + -1 exit + else + 2drop + then + \ Drop the size as we don't need it + decode-int drop decode-int drop + dup 0= + until + 3drop + 0 exit + else + 0 + then + ; + +\ Get region size for BAR reg +: pci-bar-size@ ( bar-reg -- size ) + " reg" active-package get-package-property 0= if + begin + decode-phys \ ( reg prop prop-len phys.lo phys.mid phys.hi ) + ff and 5 pick = if + 2drop decode-int drop + decode-int + >r 3drop r> + exit + else + 2drop decode-int drop + decode-int drop + then + dup 0= + until + 3drop + 0 \ default size of 0 if BAR not found + then + ; + +\ Get base address for configured BAR reg +: pci-bar-base@ ( bar-reg -- addr.lo addr.hi -1 | 0 ) + " assigned-addresses" active-package get-package-property 0= if + begin + decode-phys \ ( reg prop prop-len phys.lo phys.mid phys.hi ) + ff and 5 pick = if + >r >r 3drop r> r> + -1 exit + else + 2drop + then + \ Drop the size as we don't need it + decode-int drop decode-int drop + dup 0= + until + 3drop + 0 exit + else + 0 + then + ; + +\ Get PCI bus address and size for configured BAR reg +: pci-bar>pci-region ( bar-reg -- addr.lo addr.hi size ) + dup + >r pci-bar-offset@ if + swap r@ pci-bar-base@ if + swap d+ + then + swap r@ pci-bar-size@ + then + r> drop + ; + [THEN] diff --git a/openbios-devel/drivers/vga.fs b/openbios-devel/drivers/vga.fs index 43c8819..bf2ae60 100644 --- a/openbios-devel/drivers/vga.fs +++ b/openbios-devel/drivers/vga.fs @@ -106,6 +106,22 @@ h# 1 constant VBE_DISPI_ENABLED ;
\ +\ PCI +\ + +" pci-bar>pci-region" (find-xt) value pci-bar>pci-region-xt +: pci-bar>pci-region pci-bar>pci-region-xt execute ; + +h# 10 constant cfg-bar0 \ Framebuffer BAR +-1 value fb-addr + +: map-fb ( -- ) + cfg-bar0 pci-bar>pci-region \ ( pci-addr.lo pci-addr.hi size ) + " pci-map-in" $call-parent + to fb-addr +; + +\ \ Publically visible words \
@@ -165,23 +181,27 @@ headerless \
: qemu-vga-driver-install ( -- ) - openbios-video-addr to frame-buffer-adr - default-font set-font + fb-addr -1 = if + map-fb fb-addr to frame-buffer-adr + default-font set-font
- frame-buffer-adr encode-int " address" property - openbios-video-width encode-int " width" property - openbios-video-height encode-int " height" property - depth-bits encode-int " depth" property - line-bytes encode-int " linebytes" property + frame-buffer-adr encode-int " address" property
- openbios-video-width openbios-video-height over char-width / over char-height / - fb8-install + openbios-video-width openbios-video-height over char-width / over char-height / + fb8-install + then ;
: qemu-vga-driver-init + vbe-init + openbios-video-width encode-int " width" property + openbios-video-height encode-int " height" property + depth-bits encode-int " depth" property + line-bytes encode-int " linebytes" property + ['] qemu-vga-driver-install is-install - ; +;
qemu-vga-driver-init
diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 8c224d6..2f845e7 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -98,12 +98,4 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, p + 8, size); } } - -#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) - size = ((VIDEO_DICT_VALUE(video.h) * VIDEO_DICT_VALUE(video.rb)) + 0xfff) & ~0xfff; - - ofmem_claim_phys( video.mphys, size, 0 ); - 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 }
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/vga_vbe.c | 9 +-------- openbios-devel/libopenbios/video_common.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 2f845e7..c03dbc7 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -55,8 +55,7 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, unsigned long rom, uint32_t rom_size) { phys_addr_t phys; - phandle_t ph, chosen, aliases, options; - char buf[6]; + phandle_t ph, chosen, aliases; int size;
phys = fb; @@ -82,12 +81,6 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, aliases = find_dev("/aliases"); set_property(aliases, "screen", path, strlen(path) + 1);
- options = find_dev("/options"); - snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.w) / FONT_WIDTH); - set_property(options, "screen-#columns", buf, strlen(buf) + 1); - snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.h) / FONT_HEIGHT); - set_property(options, "screen-#rows", buf, strlen(buf) + 1); - if (rom_size >= 8) { const char *p;
diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index 6f93157..db9e0a2 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -15,6 +15,7 @@ */
#include "config.h" +#include "libc/vsprintf.h" #include "libopenbios/bindings.h" #include "libopenbios/fontdata.h" #include "libopenbios/ofmem.h" @@ -218,6 +219,8 @@ void setup_video(phys_addr_t phys, ucell virt) /* Make everything inside the video_info structure point to the values in the Forth dictionary. Hence everything is always in sync. */ + phandle_t options; + char buf[6];
video.mphys = phys;
@@ -277,4 +280,11 @@ void setup_video(phys_addr_t phys, ucell virt) VIDEO_DICT_VALUE(video.rb) = (w * ((d + 7) / 8)); } #endif + + /* Setup screen-#rows/screen-#columns */ + options = find_dev("/options"); + snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.w) / FONT_WIDTH); + set_property(options, "screen-#columns", buf, strlen(buf) + 1); + snprintf(buf, sizeof(buf), FMT_ucell, VIDEO_DICT_VALUE(video.h) / FONT_HEIGHT); + set_property(options, "screen-#rows", buf, strlen(buf) + 1); }
Previously the romvec stdin/stdout ihandles were configured so that they were set to the current stdin and stdout paths at initialisation time. Unfortunately as stdin/stdout can be changed with the input and output words, they can end up pointing to invalid ihandles causing a crash when trying to output to the console.
Fix this by pointing the romvec structure to the address of the stdin/stdout variables so that they are always in sync.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/romvec.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/openbios-devel/arch/sparc32/romvec.c b/openbios-devel/arch/sparc32/romvec.c index 2e154c1..b1083c3 100644 --- a/openbios-devel/arch/sparc32/romvec.c +++ b/openbios-devel/arch/sparc32/romvec.c @@ -25,7 +25,6 @@ #endif
char obp_stdin, obp_stdout; -static int obp_fd_stdin, obp_fd_stdout; const char *obp_stdin_path, *obp_stdout_path;
struct linux_arguments_v0 obp_arg; @@ -498,15 +497,12 @@ init_openprom(void) romvec0.pv_v2bootargs.bootpath = &bootpath;
romvec0.pv_v2bootargs.bootargs = &obp_arg.argv[1]; - romvec0.pv_v2bootargs.fd_stdin = &obp_fd_stdin; - romvec0.pv_v2bootargs.fd_stdout = &obp_fd_stdout;
- push_str(obp_stdin_path); - fword("open-dev"); - obp_fd_stdin = POP(); - push_str(obp_stdout_path); - fword("open-dev"); - obp_fd_stdout = POP(); + /* Point fd_stdin/fd_stdout to the Forth stdin/stdout variables */ + fword("stdin"); + romvec0.pv_v2bootargs.fd_stdin = cell2pointer(POP()); + fword("stdout"); + romvec0.pv_v2bootargs.fd_stdout = cell2pointer(POP());
romvec0.v3_memalloc = obp_memalloc_handler;
This means we can remove this code from vga_vbe_init() and move it in to the generic display system. As part of this, we alter the "input" and "output" words so that they update the stdin/stdout handles under /chosen.
While we are here, fix up the various architectures so that they don't call "input" and "output" themselves - this is now handled by the Forth console.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/ppc/qemu/init.c | 18 ------------------ openbios-devel/arch/sparc32/openbios.c | 16 ++-------------- openbios-devel/arch/sparc64/openbios.c | 18 ------------------ openbios-devel/drivers/vga_vbe.c | 10 +--------- openbios-devel/forth/admin/iocontrol.fs | 16 ++++++++++++++++ openbios-devel/forth/device/display.fs | 8 ++++++++ 6 files changed, 27 insertions(+), 59 deletions(-)
diff --git a/openbios-devel/arch/ppc/qemu/init.c b/openbios-devel/arch/ppc/qemu/init.c index 345fc69..54ac6f2 100644 --- a/openbios-devel/arch/ppc/qemu/init.c +++ b/openbios-devel/arch/ppc/qemu/init.c @@ -870,18 +870,6 @@ arch_of_init(void) fword("find-device");
push_str(stdin_path); - fword("open-dev"); - fword("encode-int"); - push_str("stdin"); - fword("property"); - - push_str(stdout_path); - fword("open-dev"); - fword("encode-int"); - push_str("stdout"); - fword("property"); - - push_str(stdin_path); fword("pathres-resolve-aliases"); push_str("input-device"); fword("$setenv"); @@ -891,12 +879,6 @@ arch_of_init(void) push_str("output-device"); fword("$setenv");
- push_str(stdin_path); - fword("input"); - - push_str(stdout_path); - fword("output"); - #if 0 if(getbool("tty-interface?") == 1) #endif diff --git a/openbios-devel/arch/sparc32/openbios.c b/openbios-devel/arch/sparc32/openbios.c index 40948d1..542ca80 100644 --- a/openbios-devel/arch/sparc32/openbios.c +++ b/openbios-devel/arch/sparc32/openbios.c @@ -748,7 +748,6 @@ static void setup_stdio(void) { char nographic; const char *stdin, *stdout; - phandle_t chosen;
fw_cfg_read(FW_CFG_NOGRAPHIC, &nographic, 1); if (nographic) { @@ -766,6 +765,8 @@ static void setup_stdio(void) push_str("/"); fword("find-device");
+ /* stdin-path/stdout-path properties aren't part of the spec + but Solaris needs them */ push_str(stdin); fword("pathres-resolve-aliases"); fword("encode-string"); @@ -778,16 +779,6 @@ static void setup_stdio(void) push_str("stdout-path"); fword("property");
- chosen = find_dev("/chosen"); - push_str(stdin); - fword("open-dev"); - set_int_property(chosen, "stdin", POP()); - - chosen = find_dev("/chosen"); - push_str(stdout); - fword("open-dev"); - set_int_property(chosen, "stdout", POP()); - push_str(stdin); push_str("input-device"); fword("$setenv"); @@ -796,9 +787,6 @@ static void setup_stdio(void) push_str("output-device"); fword("$setenv");
- push_str(stdin); - fword("input"); - obp_stdin_path = stdin; obp_stdout_path = stdout; } diff --git a/openbios-devel/arch/sparc64/openbios.c b/openbios-devel/arch/sparc64/openbios.c index b1e5f47..51d181f 100644 --- a/openbios-devel/arch/sparc64/openbios.c +++ b/openbios-devel/arch/sparc64/openbios.c @@ -505,30 +505,12 @@ void arch_nvram_get(char *data) }
push_str(stdin_path); - fword("open-dev"); - fword("encode-int"); - push_str("stdin"); - fword("property"); - - push_str(stdout_path); - fword("open-dev"); - fword("encode-int"); - push_str("stdout"); - fword("property"); - - push_str(stdin_path); push_str("input-device"); fword("$setenv");
push_str(stdout_path); push_str("output-device"); fword("$setenv"); - - push_str(stdin_path); - fword("input"); - - push_str(stdout_path); - fword("output"); }
void arch_nvram_put(char *data) diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index c03dbc7..02fbfb4 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -55,7 +55,7 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, unsigned long rom, uint32_t rom_size) { phys_addr_t phys; - phandle_t ph, chosen, aliases; + phandle_t ph; int size;
phys = fb; @@ -73,14 +73,6 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, ph = get_cur_dev(); #endif
- chosen = find_dev("/chosen"); - push_str(path); - fword("open-dev"); - set_int_property(chosen, "display", POP()); - - aliases = find_dev("/aliases"); - set_property(aliases, "screen", path, strlen(path) + 1); - if (rom_size >= 8) { const char *p;
diff --git a/openbios-devel/forth/admin/iocontrol.fs b/openbios-devel/forth/admin/iocontrol.fs index 0268ab3..c28adad 100644 --- a/openbios-devel/forth/admin/iocontrol.fs +++ b/openbios-devel/forth/admin/iocontrol.fs @@ -36,6 +36,14 @@ variable stdin close-dev then stdin ! + + \ update /chosen + my-self active-package 0 to my-self + " /chosen" find-package if + active-package! + stdin @ encode-int " stdin" property + then + active-package! to my-self ;
: output ( dev-str dev-len -- ) @@ -57,6 +65,14 @@ variable stdin \ close old stdout stdout @ ?dup if close-dev then stdout ! + + \ update /chosen + my-self active-package 0 to my-self + " /chosen" find-package if + active-package! + stdout @ encode-int " stdout" property + then + active-package! to my-self ;
: io ( dev-str dev-len -- ) diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index 6d77dfa..8a895d6 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -356,6 +356,14 @@ defer fb8-invertrect
my-self to display-ih
+ \ set /chosen display property + my-self active-package 0 to my-self + " /chosen" (find-dev) 0<> if + active-package! + display-ih encode-int " display" property + then + active-package! to my-self + \ set defer functions to 8bit versions
['] fb8-draw-character to draw-character
As these pass requests up the instance chain, make sure we do the real work in the IOMMU map-in and map-in words too.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/tree.fs | 2 ++ openbios-devel/drivers/iommu.c | 40 +++++++++++++++++++++++++++++++++ openbios-devel/drivers/sbus.fs | 42 +++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+)
diff --git a/openbios-devel/arch/sparc32/tree.fs b/openbios-devel/arch/sparc32/tree.fs index 0f31f4f..58e8339 100644 --- a/openbios-devel/arch/sparc32/tree.fs +++ b/openbios-devel/arch/sparc32/tree.fs @@ -55,6 +55,8 @@ new-device : close ; : encode-unit encode-unit-sbus ; : decode-unit decode-unit-sbus ; + : map-in map-in-sbus ; + : map-out map-out-sbus ; finish-device
[IFDEF] CONFIG_BPP diff --git a/openbios-devel/drivers/iommu.c b/openbios-devel/drivers/iommu.c index 45005c1..0fd5018 100644 --- a/openbios-devel/drivers/iommu.c +++ b/openbios-devel/drivers/iommu.c @@ -6,6 +6,7 @@ **/ #include "config.h" #include "libopenbios/bindings.h" +#include "libopenbios/ofmem.h" #include "drivers/drivers.h" #include "iommu.h" #include "arch/sparc32/ofmem_sparc32.h" @@ -148,6 +149,42 @@ iommu_init(struct iommu *t, uint64_t base) return regs; }
+/* ( addr.lo addr.hi size -- virt ) */ + +static void +ob_iommu_map_in(void) +{ + phys_addr_t phys; + ucell size, virt, align; + + size = POP(); + POP(); + phys = POP(); + + /* Make sure we are page-aligned at a minimum */ + align = size; + if (align < PAGE_SIZE) { + align = PAGE_SIZE; + } + + ofmem_claim_phys(phys, size, 0); + virt = ofmem_claim_virt(-1, size, align); + ofmem_map(phys, virt, size, ofmem_arch_default_translation_mode(phys)); + + PUSH(virt); +} + +/* ( virt size ) */ + +static void +ob_iommu_map_out(void) +{ + ucell size = POP(); + ucell virt = POP(); + + ofmem_unmap(virt, size); +} + void ob_init_iommu(uint64_t base) { @@ -172,4 +209,7 @@ ob_init_iommu(uint64_t base) fword("encode+"); push_str("reg"); fword("property"); + + bind_func("map-in", ob_iommu_map_in); + bind_func("map-out", ob_iommu_map_out); } diff --git a/openbios-devel/drivers/sbus.fs b/openbios-devel/drivers/sbus.fs index 409443b..11a2365 100644 --- a/openbios-devel/drivers/sbus.fs +++ b/openbios-devel/drivers/sbus.fs @@ -16,3 +16,45 @@ " ," pocket tmpstrcat >r rot pocket tohexstr r> tmpstrcat drop ; + +\ Convert sbus unit (from decode-unit) to physical address using +\ sbus node ranges property + +: sbus-unit>addr ( phys.lo phys.hi -- phys.lo phys.hi -1 | 0 ) + " ranges" my-self ihandle>phandle + get-package-property 0= if ( phys.lo phys.hi prop prop-len ) + begin + 2over swap drop 0 swap \ force phys.lo to zero for matching + 2swap ( unit.phys.lo unit.phys.hi 0 phys.hi res prop prop-len ) + 0 -rot ( unit.phys.lo unit.phys.hi res prop prop-len ) + 2 0 do + decode-int -rot >r >r ( unit.phys.lo unit.phys.hi res phys.x -- R: prop-len prop ) + rot ( unit.phys.lo res phys.x phys.hi ) + = if + 1+ + then ( unit.phys.lo res ) + r> r> ( unit.phys.lo res prop prop-len ) + loop + rot ( prop prop-len res ) + 2 = if \ did we match the unit address? if so, return the physical address + decode-phys 2swap 2drop 2swap ( unit.phys.lo unit.phys.hi phys.lo phys.hi ) + drop 0 d+ \ force unit.phys.hi to zero and add address for final offset + -1 exit + else + decode-phys 2drop decode-int drop \ drop the size and carry on + then + dup 0= until + 2drop 2drop 0 + then +; + +: map-in-sbus ( phys.lo phys.hi size ) + >r sbus-unit>addr if + r@ " map-in" $call-parent + then + r> drop +; + +: map-out-sbus ( virt ) + " map-in" $call-parent +;
Implement a C wrapper around the Forth probe-self word and test it by moving TCX package properties to tcx.fs.
Note that the probe-self-sbus word is currently hard-coded to invoke the TCX driver FCode - this is only temporary and will be replaced when we have a working cpeek implementation.
Also remove the creation of the SUNW,tcx package from tree.fs since this is now done as part of probe-self-sbus.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/tree.fs | 19 ---------------- openbios-devel/drivers/iommu.c | 12 ++-------- openbios-devel/drivers/sbus.c | 41 ++++++++++++++++++++++++----------- openbios-devel/drivers/sbus.fs | 18 +++++++++++++++ openbios-devel/drivers/tcx.fs | 23 ++++++++++++++++++++ 5 files changed, 71 insertions(+), 42 deletions(-)
diff --git a/openbios-devel/arch/sparc32/tree.fs b/openbios-devel/arch/sparc32/tree.fs index 58e8339..c82bb17 100644 --- a/openbios-devel/arch/sparc32/tree.fs +++ b/openbios-devel/arch/sparc32/tree.fs @@ -70,25 +70,6 @@ finish-device
" /iommu/sbus" find-device new-device - " SUNW,tcx" device-name - " display" device-type - h# 1d encode-int " vbporch" property - h# a0 encode-int " hbporch" property - h# 06 encode-int " vsync" property - h# 88 encode-int " hsync" property - h# 03 encode-int " vfporch" property - h# 18 encode-int " hfporch" property - h# 03dfd240 encode-int " pixfreq" property - h# 3c encode-int " vfreq" property - h# 300 encode-int " height" property - h# 400 encode-int " width" property - h# 400 encode-int " linebytes" property - 5 encode-int 0 encode-int encode+ " intr" property - 5 encode-int " interrupts" property -finish-device - -" /iommu/sbus" find-device -new-device " espdma" device-name external : encode-unit encode-unit-sbus ; diff --git a/openbios-devel/drivers/iommu.c b/openbios-devel/drivers/iommu.c index 0fd5018..7314bdd 100644 --- a/openbios-devel/drivers/iommu.c +++ b/openbios-devel/drivers/iommu.c @@ -155,21 +155,13 @@ static void ob_iommu_map_in(void) { phys_addr_t phys; - ucell size, virt, align; + ucell size, virt;
size = POP(); POP(); phys = POP();
- /* Make sure we are page-aligned at a minimum */ - align = size; - if (align < PAGE_SIZE) { - align = PAGE_SIZE; - } - - ofmem_claim_phys(phys, size, 0); - virt = ofmem_claim_virt(-1, size, align); - ofmem_map(phys, virt, size, ofmem_arch_default_translation_mode(phys)); + virt = ofmem_map_io(phys, size);
PUSH(virt); } diff --git a/openbios-devel/drivers/sbus.c b/openbios-devel/drivers/sbus.c index 5f2592f..3257142 100644 --- a/openbios-devel/drivers/sbus.c +++ b/openbios-devel/drivers/sbus.c @@ -141,7 +141,7 @@ uint16_t graphic_depth; static void ob_tcx_init(unsigned int slot, const char *path) { - phandle_t chosen, aliases; + phandle_t chosen;
push_str(path); fword("find-device"); @@ -342,18 +342,6 @@ ob_tcx_init(unsigned int slot, const char *path) }
bind_func("hw-set-color", tcx_hw_set_color); - - /* Currently we don't have an SBus probe routine, so execute FCode - directly */ - feval("['] tcx-driver-fcode 2 cells + 1 byte-load"); - - chosen = find_dev("/chosen"); - push_str(path); - fword("open-dev"); - set_int_property(chosen, "screen", POP()); - - aliases = find_dev("/aliases"); - set_property(aliases, "screen", path, strlen(path) + 1); }
static void @@ -445,11 +433,36 @@ ob_macio_init(unsigned int slot, uint64_t base, unsigned long offset) }
static void +sbus_probe_self(unsigned int slot, unsigned long offset) +{ + /* Wrapper for calling probe-self in Forth. This is mainly because some + drivers don't handle properties correctly when the sbus node is set + as the current instance during probe. */ + char buf[6]; + + /* Make the sbus node the current instance and active package for probing */ + feval("active-package my-self"); + push_str("/iommu/sbus"); + feval("open-dev to my-self"); + + PUSH(0); + PUSH(0); + snprintf(buf, 6, "%d,%ld", slot, offset); + push_str(buf); + fword("2dup"); + fword("probe-self-sbus"); + + /* Restore */ + feval("to my-self active-package!"); +} + +static void sbus_probe_slot_ss5(unsigned int slot, uint64_t base) { // OpenBIOS and QEMU don't know how to do Sbus probing switch(slot) { case 3: // SUNW,tcx + sbus_probe_self(slot, 0); ob_tcx_init(slot, "/iommu/sbus/SUNW,tcx"); break; case 4: @@ -472,6 +485,7 @@ sbus_probe_slot_ss10(unsigned int slot, uint64_t base) // OpenBIOS and QEMU don't know how to do Sbus probing switch(slot) { case 2: // SUNW,tcx + sbus_probe_self(slot, 0); ob_tcx_init(slot, "/iommu/sbus/SUNW,tcx"); break; case 0xf: // le, esp, bpp, power-management @@ -490,6 +504,7 @@ sbus_probe_slot_ss600mp(unsigned int slot, uint64_t base) // OpenBIOS and QEMU don't know how to do Sbus probing switch(slot) { case 2: // SUNW,tcx + sbus_probe_self(slot, 0); ob_tcx_init(slot, "/iommu/sbus/SUNW,tcx"); break; case 0xf: // le, esp, bpp, power-management diff --git a/openbios-devel/drivers/sbus.fs b/openbios-devel/drivers/sbus.fs index 11a2365..20a8132 100644 --- a/openbios-devel/drivers/sbus.fs +++ b/openbios-devel/drivers/sbus.fs @@ -58,3 +58,21 @@ : map-out-sbus ( virt ) " map-in" $call-parent ; + +\ ------------------------------------------------------------------------- +\ SBus probe +\ ------------------------------------------------------------------------- + +: probe-self-sbus ( arg-adr arg-len reg-adr reg-len fcode-adr fcode-len -- ) + 2drop + new-device + set-args + + \ Note: this is currently hardcoded to TCX for testing as we don't have + \ cpeek (yet). Once cpeek is in place, adapting this to probe any slot + \ will be faily easy. + " tcx-driver-fcode" $find drop 2 cells + + 1 byte-load + + finish-device +; diff --git a/openbios-devel/drivers/tcx.fs b/openbios-devel/drivers/tcx.fs index 19fa555..8b16858 100644 --- a/openbios-devel/drivers/tcx.fs +++ b/openbios-devel/drivers/tcx.fs @@ -30,6 +30,13 @@ fcode-version3 then ;
+\ +\ Installation +\ + +" SUNW,tcx" device-name +" display" device-type + : qemu-tcx-driver-install ( -- ) openbios-video-addr to frame-buffer-adr default-font set-font @@ -38,6 +45,22 @@ fcode-version3 ;
: qemu-tcx-driver-init + + h# 1d encode-int " vbporch" property + h# a0 encode-int " hbporch" property + h# 06 encode-int " vsync" property + h# 88 encode-int " hsync" property + h# 03 encode-int " vfporch" property + h# 18 encode-int " hfporch" property + h# 03dfd240 encode-int " pixfreq" property + h# 3c encode-int " vfreq" property + h# 300 encode-int " height" property + h# 400 encode-int " width" property + h# 400 encode-int " linebytes" property + + 5 encode-int 0 encode-int encode+ " intr" property + 5 encode-int " interrupts" property + ['] qemu-tcx-driver-install is-install ;
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/tcx.fs | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/openbios-devel/drivers/tcx.fs b/openbios-devel/drivers/tcx.fs index 8b16858..755399d 100644 --- a/openbios-devel/drivers/tcx.fs +++ b/openbios-devel/drivers/tcx.fs @@ -12,23 +12,25 @@ fcode-version3 \ and height, grab the ones passed in by QEMU/generated by OpenBIOS \
-: openbios-video-addr - " openbios-video-addr" $find if - cell+ @ +: (find-xt) \ ( str len -- xt | -1 ) + $find if + exit + else + -1 then ;
-: openbios-video-width - " openbios-video-width" $find if - cell+ @ - then -; +" openbios-video-addr" (find-xt) cell+ value openbios-video-addr-xt +" openbios-video-width" (find-xt) cell+ value openbios-video-width-xt +" openbios-video-height" (find-xt) cell+ value openbios-video-height-xt +" depth-bits" (find-xt) cell+ value depth-bits-xt +" line-bytes" (find-xt) cell+ value line-bytes-xt
-: openbios-video-height - " openbios-video-height" $find if - cell+ @ - then -; +: openbios-video-addr openbios-video-addr-xt @ ; +: openbios-video-width openbios-video-width-xt @ ; +: openbios-video-height openbios-video-height-xt @ ; +: depth-bits depth-bits-xt @ ; +: line-bytes line-bytes-xt @ ;
\ \ Installation @@ -54,9 +56,10 @@ fcode-version3 h# 18 encode-int " hfporch" property h# 03dfd240 encode-int " pixfreq" property h# 3c encode-int " vfreq" property - h# 300 encode-int " height" property - h# 400 encode-int " width" property - h# 400 encode-int " linebytes" property + + openbios-video-height encode-int " height" property + openbios-video-width encode-int " width" property + line-bytes encode-int " linebytes" property
5 encode-int 0 encode-int encode+ " intr" property 5 encode-int " interrupts" property
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/console.c | 20 --- openbios-devel/drivers/sbus.c | 199 ------------------------------ openbios-devel/drivers/tcx.fs | 170 ++++++++++++++++++++++++- openbios-devel/include/drivers/drivers.h | 1 - 4 files changed, 166 insertions(+), 224 deletions(-)
diff --git a/openbios-devel/arch/sparc32/console.c b/openbios-devel/arch/sparc32/console.c index 91587fc..dc0b524 100644 --- a/openbios-devel/arch/sparc32/console.c +++ b/openbios-devel/arch/sparc32/console.c @@ -22,32 +22,12 @@
#define VMEM_BASE 0x00800000ULL #define VMEM_SIZE (1024*768*1) -#define DAC_BASE 0x00200000ULL -#define DAC_SIZE 16
unsigned char *vmem; -volatile uint32_t *dac;
void tcx_init(uint64_t base) { vmem = (unsigned char *)ofmem_map_io(base + VMEM_BASE, VMEM_SIZE); - 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 3257142..6ef6bda 100644 --- a/openbios-devel/drivers/sbus.c +++ b/openbios-devel/drivers/sbus.c @@ -141,207 +141,8 @@ uint16_t graphic_depth; static void ob_tcx_init(unsigned int slot, const char *path) { - phandle_t chosen; - push_str(path); fword("find-device"); - - PUSH(slot); - fword("encode-int"); - PUSH(0x00800000); - fword("encode-int"); - fword("encode+"); - PUSH(0x00100000); - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x02000000); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00400000); - } else { - PUSH(0x00000001); - } - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x04000000); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00400000); - } else { - PUSH(0x00000001); - } - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x06000000); - fword("encode-int"); - fword("encode+"); - PUSH(0x00800000); - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x0a000000); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00400000); - } else { - PUSH(0x00000001); - } - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x0c000000); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00800000); - } else { - PUSH(0x00000001); - } - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x0e000000); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00800000); - } else { - PUSH(0x00000001); - } - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x00700000); - fword("encode-int"); - fword("encode+"); - PUSH(0x00001000); - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x00200000); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00004000); - } else { - PUSH(0x00000004); - } - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00301000); - } else { - PUSH(0x00300000); - } - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00001000); - } else { - PUSH(0x0000081c); - } - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x00000000); - fword("encode-int"); - fword("encode+"); - PUSH(0x00010000); - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x00240000); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00004000); - } else { - PUSH(0x00000004); - } - fword("encode-int"); - fword("encode+"); - - PUSH(slot); - fword("encode-int"); - fword("encode+"); - PUSH(0x00280000); - fword("encode-int"); - fword("encode+"); - if (graphic_depth == 24) { - PUSH(0x00008000); - } else { - PUSH(0x00000001); - } - fword("encode-int"); - fword("encode+"); - - push_str("reg"); - fword("property"); - - PUSH((int)graphic_depth); - fword("encode-int"); - push_str("depth"); - fword("property"); - - if (graphic_depth == 8) { - push_str("true"); - fword("encode-string"); - push_str("tcx-8-bit"); - fword("property"); - } - - /* Even with a 24-bit enabled TCX card, the control plane is - used in 8-bit mode. So force the video subsystem into 8-bit - mode before initialisation. */ - if (graphic_depth == 24) { - VIDEO_DICT_VALUE(video.depth) = 8; - VIDEO_DICT_VALUE(video.rb) = VIDEO_DICT_VALUE(video.w); - - chosen = get_cur_dev(); - set_int_property(chosen, "linebytes", VIDEO_DICT_VALUE(video.rb)); - } - - bind_func("hw-set-color", tcx_hw_set_color); }
static void diff --git a/openbios-devel/drivers/tcx.fs b/openbios-devel/drivers/tcx.fs index 755399d..2e50c83 100644 --- a/openbios-devel/drivers/tcx.fs +++ b/openbios-devel/drivers/tcx.fs @@ -33,6 +33,146 @@ fcode-version3 : line-bytes line-bytes-xt @ ;
\ +\ Registers +\ + +h# 0 constant tcx-off1 +h# 10000 constant /tcx-off1 + +h# 200000 constant tcx-off-dac +h# 4000 constant /tcx-off-dac-24 +h# 4 constant /tcx-off-dac-8 + +h# 240000 constant tcx-off3 +h# 4000 constant /tcx-off3-24 +h# 4 constant /tcx-off3-8 + +h# 280000 constant tcx-off4 +h# 8000 constant /tcx-off4-24 +h# 1 constant /tcx-off4-8 + +h# 301000 constant tcx-off5-24 +h# 300000 constant tcx-off5-8 +h# 1000 constant /tcx-off5-24 +h# 81c constant /tcx-off5-8 + +h# 700000 constant tcx-off6 +h# 1000 constant /tcx-off6 + +h# 800000 constant tcx-off-fb +h# 100000 constant /tcx-off-fb + +h# 2000000 constant tcx-off8 +h# 400000 constant /tcx-off8-24 +h# 1 constant /tcx-off8-8 + +h# 4000000 constant tcx-off9 +h# 400000 constant /tcx-off9-24 +h# 1 constant /tcx-off9-8 + +h# 6000000 constant tcx-off10 +h# 800000 constant /tcx-off10 + +h# a000000 constant tcx-off11 +h# 400000 constant /tcx-off11-24 +h# 1 constant /tcx-off11-8 + +h# c000000 constant tcx-off12 +h# 800000 constant /tcx-off12-24 +h# 1 constant /tcx-off12-8 + +h# e000000 constant tcx-off13 +h# 800000 constant /tcx-off13-24 +h# 1 constant /tcx-off13-8 + +: >tcx-reg-spec ( offset size -- encoded-reg ) + >r 0 my-address d+ my-space encode-phys r> encode-int encode+ +; + +: tcx-8bit-reg + \ WARNING: order is important (at least to Solaris) + tcx-off-fb /tcx-off-fb >tcx-reg-spec + tcx-off8 /tcx-off8-8 >tcx-reg-spec encode+ + tcx-off9 /tcx-off9-8 >tcx-reg-spec encode+ + tcx-off10 /tcx-off10 >tcx-reg-spec encode+ + tcx-off11 /tcx-off11-8 >tcx-reg-spec encode+ + tcx-off12 /tcx-off12-8 >tcx-reg-spec encode+ + tcx-off13 /tcx-off13-8 >tcx-reg-spec encode+ + tcx-off6 /tcx-off6 >tcx-reg-spec encode+ + tcx-off-dac /tcx-off-dac-8 >tcx-reg-spec encode+ + tcx-off5-8 /tcx-off5-8 >tcx-reg-spec encode+ + tcx-off1 /tcx-off1 >tcx-reg-spec encode+ + tcx-off3 /tcx-off3-8 >tcx-reg-spec encode+ + tcx-off4 /tcx-off4-8 >tcx-reg-spec encode+ + " reg" property +; + +: tcx-24bit-reg + \ WARNING: order is important (at least to Solaris) + tcx-off-fb /tcx-off-fb >tcx-reg-spec + tcx-off8 /tcx-off8-24 >tcx-reg-spec encode+ + tcx-off9 /tcx-off9-24 >tcx-reg-spec encode+ + tcx-off10 /tcx-off10 >tcx-reg-spec encode+ + tcx-off11 /tcx-off11-24 >tcx-reg-spec encode+ + tcx-off12 /tcx-off12-24 >tcx-reg-spec encode+ + tcx-off13 /tcx-off13-24 >tcx-reg-spec encode+ + tcx-off6 /tcx-off6 >tcx-reg-spec encode+ + tcx-off-dac /tcx-off-dac-24 >tcx-reg-spec encode+ + tcx-off5-24 /tcx-off5-24 >tcx-reg-spec encode+ + tcx-off1 /tcx-off1 >tcx-reg-spec encode+ + tcx-off3 /tcx-off3-24 >tcx-reg-spec encode+ + tcx-off4 /tcx-off4-24 >tcx-reg-spec encode+ + " reg" property +; + +: do-map-in ( offset size -- virt ) + >r my-space r> " map-in" $call-parent +; + +: do-map-out ( virt size ) + " map-out" $call-parent +; + +\ +\ DAC +\ + +-1 value tcx-dac +-1 value /tcx-dac + +: dac! ( data reg# -- ) + >r dup 2dup bljoin r> tcx-dac + l! +; + +: color! ( r g b c# -- ) + 0 dac! ( r g b ) + swap rot ( b g r ) + 4 dac! ( b g ) + 4 dac! ( b ) + 4 dac! ( ) +; + +\ +\ Mapping +\ + +: dac-map + tcx-off-dac /tcx-dac do-map-in to tcx-dac +; + +: map-regs + dac-map +; + +external + +: hw-set-color + color! +; + +headerless + +\ \ Installation \
@@ -40,14 +180,36 @@ fcode-version3 " display" device-type
: qemu-tcx-driver-install ( -- ) - openbios-video-addr to frame-buffer-adr - default-font set-font - openbios-video-width openbios-video-height over char-width / over char-height / - fb8-install + tcx-dac -1 = if + map-regs + openbios-video-addr to frame-buffer-adr + default-font set-font + + frame-buffer-adr encode-int " address" property + + openbios-video-width openbios-video-height over char-width / over char-height / + fb8-install + then ;
: qemu-tcx-driver-init
+ \ Handle differences between 8-bit/24-bit mode + depth-bits 8 = if + tcx-8bit-reg + /tcx-off-dac-8 to /tcx-dac + " true" encode-string " tcx-8-bit" property + else + tcx-24bit-reg + /tcx-off-dac-24 to /tcx-dac + + \ Even with a 24-bit enabled TCX card, the control plane is + \ used in 8-bit mode. So force the video subsystem into 8-bit + \ mode before initialisation. + 8 depth-bits-xt ! + openbios-video-width line-bytes-xt ! + then + h# 1d encode-int " vbporch" property h# a0 encode-int " hbporch" property h# 06 encode-int " vsync" property diff --git a/openbios-devel/include/drivers/drivers.h b/openbios-devel/include/drivers/drivers.h index d041e81..d139ace 100644 --- a/openbios-devel/include/drivers/drivers.h +++ b/openbios-devel/include/drivers/drivers.h @@ -47,7 +47,6 @@ 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
Finally we can now fix up setup_video() so that it has no knowledge of fixed addresse but simply refers to the underlying Forth variables as per the specification. Touch up various places as a result of this, but we can now remove the bogus openbios-video-addr and just use frame-buffer-adr instead.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/console.c | 18 ------------------ openbios-devel/arch/sparc32/openbios.c | 3 +-- openbios-devel/drivers/pci.c | 8 ++++---- openbios-devel/drivers/tcx.fs | 11 +++++++---- openbios-devel/drivers/vga.fs | 2 -- openbios-devel/drivers/vga_vbe.c | 10 +--------- openbios-devel/forth/device/display.fs | 1 - openbios-devel/include/drivers/drivers.h | 1 - openbios-devel/include/libopenbios/video.h | 3 +-- openbios-devel/libopenbios/video_common.c | 7 ++----- 10 files changed, 16 insertions(+), 48 deletions(-)
diff --git a/openbios-devel/arch/sparc32/console.c b/openbios-devel/arch/sparc32/console.c index dc0b524..f3d1fad 100644 --- a/openbios-devel/arch/sparc32/console.c +++ b/openbios-devel/arch/sparc32/console.c @@ -15,24 +15,6 @@ #ifdef CONFIG_DEBUG_CONSOLE
/* ****************************************************************** - * simple polling video/keyboard console functions - * ****************************************************************** */ - -#ifdef CONFIG_DEBUG_CONSOLE_VIDEO - -#define VMEM_BASE 0x00800000ULL -#define VMEM_SIZE (1024*768*1) - -unsigned char *vmem; - -void tcx_init(uint64_t base) -{ - vmem = (unsigned char *)ofmem_map_io(base + VMEM_BASE, VMEM_SIZE); -} - -#endif - -/* ****************************************************************** * common functions, implementing simple concurrent console * ****************************************************************** */
diff --git a/openbios-devel/arch/sparc32/openbios.c b/openbios-devel/arch/sparc32/openbios.c index 542ca80..a97482d 100644 --- a/openbios-devel/arch/sparc32/openbios.c +++ b/openbios-devel/arch/sparc32/openbios.c @@ -863,7 +863,7 @@ arch_init( void ) #endif #ifdef CONFIG_DRIVER_SBUS #ifdef CONFIG_DEBUG_CONSOLE_VIDEO - setup_video(hwdef->tcx_base + 0x00800000ULL, (unsigned long)vmem); + setup_video(); #endif ob_sbus_init(hwdef->iommu_base + 0x1000ULL, qemu_machine_type); #endif @@ -956,7 +956,6 @@ int openbios(void) CONFIG_SERIAL_SPEED); #endif #ifdef CONFIG_DEBUG_CONSOLE_VIDEO - tcx_init(hwdef->tcx_base); kbd_init(hwdef->ms_kb_base); #endif #endif diff --git a/openbios-devel/drivers/pci.c b/openbios-devel/drivers/pci.c index 368d7b5..fbc3c8e 100644 --- a/openbios-devel/drivers/pci.c +++ b/openbios-devel/drivers/pci.c @@ -361,11 +361,11 @@ ob_pci_map_in(int *idx) #if defined(CONFIG_OFMEM) ofmem_claim_phys(phys, size, 0);
-#if defined(CONFIG_SPARC64) - /* Fix virtual address on SPARC64 somewhere else */ - virt = ofmem_claim_virt(0xfe000000ULL, size, 0); -#else +#if defined(CONFIG_PPC) + /* For some reason PPC gets upset when virt != phys for map-in... */ virt = ofmem_claim_virt(phys, size, 0); +#else + virt = ofmem_claim_virt(-1, size, size); #endif
ofmem_map(phys, virt, size, ofmem_arch_io_translation_mode(phys)); diff --git a/openbios-devel/drivers/tcx.fs b/openbios-devel/drivers/tcx.fs index 2e50c83..2ae1c4e 100644 --- a/openbios-devel/drivers/tcx.fs +++ b/openbios-devel/drivers/tcx.fs @@ -20,13 +20,11 @@ fcode-version3 then ;
-" openbios-video-addr" (find-xt) cell+ value openbios-video-addr-xt " openbios-video-width" (find-xt) cell+ value openbios-video-width-xt " openbios-video-height" (find-xt) cell+ value openbios-video-height-xt " depth-bits" (find-xt) cell+ value depth-bits-xt " line-bytes" (find-xt) cell+ value line-bytes-xt
-: openbios-video-addr openbios-video-addr-xt @ ; : openbios-video-width openbios-video-width-xt @ ; : openbios-video-height openbios-video-height-xt @ ; : depth-bits depth-bits-xt @ ; @@ -139,6 +137,7 @@ h# 1 constant /tcx-off13-8
-1 value tcx-dac -1 value /tcx-dac +-1 value fb-addr
: dac! ( data reg# -- )
r dup 2dup bljoin r> tcx-dac + l!
@@ -160,8 +159,12 @@ h# 1 constant /tcx-off13-8 tcx-off-dac /tcx-dac do-map-in to tcx-dac ;
+: fb-map + tcx-off-fb h# c0000 do-map-in to fb-addr +; + : map-regs - dac-map + dac-map fb-map ;
external @@ -182,7 +185,7 @@ headerless : qemu-tcx-driver-install ( -- ) tcx-dac -1 = if map-regs - openbios-video-addr to frame-buffer-adr + fb-addr to frame-buffer-adr default-font set-font
frame-buffer-adr encode-int " address" property diff --git a/openbios-devel/drivers/vga.fs b/openbios-devel/drivers/vga.fs index bf2ae60..d359923 100644 --- a/openbios-devel/drivers/vga.fs +++ b/openbios-devel/drivers/vga.fs @@ -19,13 +19,11 @@ fcode-version3 then ;
-" openbios-video-addr" (find-xt) cell+ value openbios-video-addr-xt " openbios-video-width" (find-xt) cell+ value openbios-video-width-xt " openbios-video-height" (find-xt) cell+ value openbios-video-height-xt " depth-bits" (find-xt) cell+ value depth-bits-xt " line-bytes" (find-xt) cell+ value line-bytes-xt
-: openbios-video-addr openbios-video-addr-xt @ ; : openbios-video-width openbios-video-width-xt @ ; : openbios-video-height openbios-video-height-xt @ ; : depth-bits depth-bits-xt @ ; diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 02fbfb4..fc1fffd 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -54,18 +54,10 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, unsigned long rom, uint32_t rom_size) { - phys_addr_t phys; phandle_t ph; int size;
- phys = fb; - -#if defined(CONFIG_SPARC64) - /* Fix virtual address on SPARC64 somewhere else */ - fb = 0xfe000000ULL; -#endif - - setup_video(phys, fb); + setup_video();
#if 0 ph = find_dev(path); diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index 8a895d6..5779ca8 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -51,7 +51,6 @@ create color-palette 100 cells allot 0 value display-ih
\ internal values -0 value openbios-video-addr 0 value openbios-video-height 0 value openbios-video-width
diff --git a/openbios-devel/include/drivers/drivers.h b/openbios-devel/include/drivers/drivers.h index d139ace..66c4ab7 100644 --- a/openbios-devel/include/drivers/drivers.h +++ b/openbios-devel/include/drivers/drivers.h @@ -46,7 +46,6 @@ static inline int is_newworld(void) int ob_sbus_init(uint64_t base, int machine_id);
/* arch/sparc32/console.c */ -void tcx_init(uint64_t base); 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 5e9abb7..8c32858 100644 --- a/openbios-devel/include/libopenbios/video.h +++ b/openbios-devel/include/libopenbios/video.h @@ -19,7 +19,7 @@
#define VGA_DEFAULT_LINEBYTES (VGA_DEFAULT_WIDTH*((VGA_DEFAULT_DEPTH+7)/8))
-void setup_video(phys_addr_t phys, ucell virt); +void setup_video(void); unsigned long video_get_color(int col_ind); void video_set_color(int ind, unsigned long color); void video_mask_blit(void); @@ -28,7 +28,6 @@ void video_fill_rect(void);
extern struct video_info { 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 db9e0a2..51596e8 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -214,7 +214,7 @@ video_fill_rect(void) } }
-void setup_video(phys_addr_t phys, ucell virt) +void setup_video() { /* Make everything inside the video_info structure point to the values in the Forth dictionary. Hence everything is always in @@ -222,12 +222,10 @@ void setup_video(phys_addr_t phys, ucell virt) phandle_t options; char buf[6];
- video.mphys = phys; - feval("['] display-ih cell+"); video.ih = cell2pointer(POP());
- feval("['] openbios-video-addr cell+"); + feval("['] frame-buffer-adr cell+"); video.mvirt = cell2pointer(POP()); feval("['] openbios-video-width cell+"); video.w = cell2pointer(POP()); @@ -260,7 +258,6 @@ void setup_video(phys_addr_t phys, ucell virt) feval("to (romfont-width)");
/* Initialise the structure */ - VIDEO_DICT_VALUE(video.mvirt) = virt; VIDEO_DICT_VALUE(video.w) = VGA_DEFAULT_WIDTH; VIDEO_DICT_VALUE(video.h) = VGA_DEFAULT_HEIGHT; VIDEO_DICT_VALUE(video.depth) = VGA_DEFAULT_DEPTH;
Since all of the colour state is now held in Forth, remove the hack that was video_set_color(). Anything that needs to change the pallette (including MOL) can just call "color!" on the driver package.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/tcx.fs | 12 ++++-------- openbios-devel/drivers/vga.fs | 10 +++------- openbios-devel/forth/device/display.fs | 2 +- openbios-devel/include/libopenbios/video.h | 1 - openbios-devel/libopenbios/video_common.c | 29 ---------------------------- 5 files changed, 8 insertions(+), 46 deletions(-)
diff --git a/openbios-devel/drivers/tcx.fs b/openbios-devel/drivers/tcx.fs index 2ae1c4e..ad21ff9 100644 --- a/openbios-devel/drivers/tcx.fs +++ b/openbios-devel/drivers/tcx.fs @@ -143,6 +143,8 @@ h# 1 constant /tcx-off13-8
r dup 2dup bljoin r> tcx-dac + l!
;
+external + : color! ( r g b c# -- ) 0 dac! ( r g b ) swap rot ( b g r ) @@ -151,6 +153,8 @@ h# 1 constant /tcx-off13-8 4 dac! ( ) ;
+headerless + \ \ Mapping \ @@ -167,14 +171,6 @@ h# 1 constant /tcx-off13-8 dac-map fb-map ;
-external - -: hw-set-color - color! -; - -headerless - \ \ Installation \ diff --git a/openbios-devel/drivers/vga.fs b/openbios-devel/drivers/vga.fs index d359923..3579532 100644 --- a/openbios-devel/drivers/vga.fs +++ b/openbios-devel/drivers/vga.fs @@ -133,7 +133,7 @@ defer mol-color! \ Perhaps for neatness this there should be a separate molvga.fs \ but let's leave it here for now.
-: hw-set-color ( r g b index -- ) +: color! ( r g b index -- ) mol-color! ;
@@ -141,16 +141,12 @@ defer mol-color!
\ Standard VGA
-: hw-set-color ( r g b index -- ) +: color! ( r g b index -- ) vga-color! ;
[THEN]
-: color! ( r g b index -- ) - hw-set-color -; - : fill-rectangle ( color_ind x y width height -- ) fb8-fillrect ; @@ -166,7 +162,7 @@ defer mol-color! c@ swap 1+ \ ( table start r table-g ) dup c@ swap 1+ \ ( table start r g table-b ) c@ 3 pick \ ( table start r g b index ) - hw-set-color \ ( table start ) + color! \ ( table start ) 1+ swap 3 + swap \ ( table+3 start+1 ) loop diff --git a/openbios-devel/forth/device/display.fs b/openbios-devel/forth/device/display.fs index 5779ca8..fff44e0 100644 --- a/openbios-devel/forth/device/display.fs +++ b/openbios-devel/forth/device/display.fs @@ -399,7 +399,7 @@ defer fb8-invertrect 1 pick @ ff00 and d# 8 rshift 2 pick @ ff and i - s" hw-set-color" $find if + s" color!" $find if execute else 2drop diff --git a/openbios-devel/include/libopenbios/video.h b/openbios-devel/include/libopenbios/video.h index 8c32858..44d7456 100644 --- a/openbios-devel/include/libopenbios/video.h +++ b/openbios-devel/include/libopenbios/video.h @@ -21,7 +21,6 @@
void setup_video(void); unsigned long video_get_color(int col_ind); -void video_set_color(int ind, unsigned long color); void video_mask_blit(void); void video_invert_rect(void); void video_fill_rect(void); diff --git a/openbios-devel/libopenbios/video_common.c b/openbios-devel/libopenbios/video_common.c index 51596e8..9bbc18c 100644 --- a/openbios-devel/libopenbios/video_common.c +++ b/openbios-devel/libopenbios/video_common.c @@ -43,35 +43,6 @@ video_get_color( int col_ind ) return 0; }
-void -video_set_color( int ind, unsigned long color ) -{ - xt_t hw_xt = 0; - - if( !VIDEO_DICT_VALUE(video.ih) || ind < 0 || ind > 255 ) - return; - video.pal[ind] = color; - - /* 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 -- ) */
void
Since the VBE initialisation is now done as part of the Forth driver, this can now be completely removed. The tiny bit of code remaining for ROM detection is moved into pci.c.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/drivers/build.xml | 1 - openbios-devel/drivers/pci.c | 33 +++++++++++----- openbios-devel/drivers/vga_vbe.c | 78 -------------------------------------- 3 files changed, 24 insertions(+), 88 deletions(-) delete mode 100644 openbios-devel/drivers/vga_vbe.c
diff --git a/openbios-devel/drivers/build.xml b/openbios-devel/drivers/build.xml index 5d7e769..bd91335 100644 --- a/openbios-devel/drivers/build.xml +++ b/openbios-devel/drivers/build.xml @@ -17,7 +17,6 @@ <object source="obio.c" condition="DRIVER_OBIO"/> <object source="vga_load_regs.c" condition="DRIVER_VGA"/> <object source="vga_set_mode.c" condition="DRIVER_VGA"/> - <object source="vga_vbe.c" condition="DRIVER_VGA"/> <object source="macio.c" condition="DRIVER_MACIO"/> <object source="pc_kbd.c" condition="DRIVER_PC_KBD"/> <object source="pc_serial.c" condition="DRIVER_PC_SERIAL"/> diff --git a/openbios-devel/drivers/pci.c b/openbios-devel/drivers/pci.c index fbc3c8e..a900ae9 100644 --- a/openbios-devel/drivers/pci.c +++ b/openbios-devel/drivers/pci.c @@ -803,15 +803,30 @@ int macio_keylargo_config_cb (const pci_config_t *config)
int vga_config_cb (const pci_config_t *config) { - if (config->assigned[0] != 0x00000000) { - vga_vbe_init(config->path, - pci_bus_addr_to_host_addr(config->assigned[0] & ~0x0000000F), - config->sizes[0], - pci_bus_addr_to_host_addr(config->assigned[1] & ~0x0000000F), - config->sizes[1]); - - /* Currently we don't read FCode from the hardware but execute it directly */ - feval("['] vga-driver-fcode 2 cells + 1 byte-load"); + unsigned long rom; + uint32_t rom_size, size; + phandle_t ph; + + if (config->assigned[0] != 0x00000000) { + setup_video(); + + rom = pci_bus_addr_to_host_addr(config->assigned[1] & ~0x0000000F); + rom_size = config->sizes[1]; + + ph = get_cur_dev(); + + if (rom_size >= 8) { + const char *p; + + p = (const char *)rom; + if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') { + size = *(uint32_t*)(p + 4); + set_property(ph, "driver,AAPL,MacOS,PowerPC", p + 8, size); + } + } + + /* Currently we don't read FCode from the hardware but execute it directly */ + feval("['] vga-driver-fcode 2 cells + 1 byte-load");
#ifdef CONFIG_MOL /* Install special words for Mac On Linux */ diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c deleted file mode 100644 index fc1fffd..0000000 --- a/openbios-devel/drivers/vga_vbe.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2004-2005 Fabrice Bellard - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License V2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include "config.h" -#include "kernel/kernel.h" -#include "libopenbios/bindings.h" -#include "drivers/pci.h" -#include "drivers/drivers.h" -#include "libopenbios/fontdata.h" -#include "asm/io.h" -#include "libc/vsprintf.h" -#include "drivers/vga.h" -#include "libopenbios/video.h" -#include "libopenbios/ofmem.h" - -/* VGA init. We use the Bochs VESA VBE extensions */ -#define VBE_DISPI_INDEX_ID 0x0 -#define VBE_DISPI_INDEX_XRES 0x1 -#define VBE_DISPI_INDEX_YRES 0x2 -#define VBE_DISPI_INDEX_BPP 0x3 -#define VBE_DISPI_INDEX_ENABLE 0x4 -#define VBE_DISPI_INDEX_BANK 0x5 -#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 -#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 -#define VBE_DISPI_INDEX_X_OFFSET 0x8 -#define VBE_DISPI_INDEX_Y_OFFSET 0x9 -#define VBE_DISPI_INDEX_NB 0xa - -#define VBE_DISPI_ID0 0xB0C0 -#define VBE_DISPI_ID1 0xB0C1 -#define VBE_DISPI_ID2 0xB0C2 - -#define VBE_DISPI_DISABLED 0x00 -#define VBE_DISPI_ENABLED 0x01 -#define VBE_DISPI_LFB_ENABLED 0x40 -#define VBE_DISPI_NOCLEARMEM 0x80 - - -void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, - unsigned long rom, uint32_t rom_size) -{ - phandle_t ph; - int size; - - setup_video(); - -#if 0 - ph = find_dev(path); -#else - ph = get_cur_dev(); -#endif - - if (rom_size >= 8) { - const char *p; - - p = (const char *)rom; - if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') { - size = *(uint32_t*)(p + 4); - set_property(ph, "driver,AAPL,MacOS,PowerPC", - p + 8, size); - } - } -}