mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-25 11:37:56 +00:00
Merge VT(9) project (a.k.a. newcons).
Reviewed by: nwhitehorn MFC_to_10_after: re approval Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
5c79f1f9df
commit
27cf7d04ef
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=259016
@ -82,7 +82,7 @@ pccarddevs.h standard \
|
||||
compile-with "${AWK} -f $S/tools/pccarddevs2h.awk $S/dev/pccard/pccarddevs" \
|
||||
no-obj no-implicit-rule before-depend \
|
||||
clean "pccarddevs.h"
|
||||
teken_state.h optional sc \
|
||||
teken_state.h optional sc | vt \
|
||||
dependency "$S/teken/gensequences $S/teken/sequences" \
|
||||
compile-with "${AWK} -f $S/teken/gensequences $S/teken/sequences > teken_state.h" \
|
||||
no-obj no-implicit-rule before-depend \
|
||||
@ -1396,6 +1396,8 @@ dev/ex/if_ex_isa.c optional ex isa
|
||||
dev/ex/if_ex_pccard.c optional ex pccard
|
||||
dev/exca/exca.c optional cbb
|
||||
dev/fatm/if_fatm.c optional fatm pci
|
||||
dev/fb/fbd.c optional fbd | vt
|
||||
dev/fb/fb_if.m optional fbd | vt
|
||||
dev/fb/splash.c optional splash
|
||||
dev/fdt/fdt_common.c optional fdt
|
||||
dev/fdt/fdt_ic_if.m optional fdt
|
||||
@ -2461,6 +2463,17 @@ dev/vge/if_vge.c optional vge
|
||||
|
||||
dev/vkbd/vkbd.c optional vkbd
|
||||
dev/vr/if_vr.c optional vr pci
|
||||
dev/vt/colors/vt_termcolors.c optional vt
|
||||
dev/vt/font/vt_font_default.c optional vt
|
||||
dev/vt/font/vt_mouse_cursor.c optional vt
|
||||
dev/vt/hw/fb/vt_fb.c optional vt
|
||||
dev/vt/hw/vga/vga.c optional vt vt_vga
|
||||
dev/vt/logo/logo_freebsd.c optional vt
|
||||
dev/vt/vt_buf.c optional vt
|
||||
dev/vt/vt_consolectl.c optional vt
|
||||
dev/vt/vt_core.c optional vt
|
||||
dev/vt/vt_font.c optional vt
|
||||
dev/vt/vt_sysmouse.c optional vt
|
||||
dev/vte/if_vte.c optional vte pci
|
||||
dev/vx/if_vx.c optional vx
|
||||
dev/vx/if_vx_eisa.c optional vx eisa
|
||||
@ -2897,6 +2910,7 @@ kern/subr_sleepqueue.c standard
|
||||
kern/subr_smp.c standard
|
||||
kern/subr_stack.c optional ddb | stack | ktr
|
||||
kern/subr_taskqueue.c standard
|
||||
kern/subr_terminal.c optional vt
|
||||
kern/subr_trap.c standard
|
||||
kern/subr_turnstile.c standard
|
||||
kern/subr_uio.c standard
|
||||
@ -3796,7 +3810,7 @@ security/mac_portacl/mac_portacl.c optional mac_portacl
|
||||
security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids
|
||||
security/mac_stub/mac_stub.c optional mac_stub
|
||||
security/mac_test/mac_test.c optional mac_test
|
||||
teken/teken.c optional sc
|
||||
teken/teken.c optional sc | vt
|
||||
ufs/ffs/ffs_alloc.c optional ffs
|
||||
ufs/ffs/ffs_balloc.c optional ffs
|
||||
ufs/ffs/ffs_inode.c optional ffs
|
||||
|
@ -241,7 +241,7 @@ dev/hyperv/vmbus/hv_connection.c optional hyperv
|
||||
dev/hyperv/vmbus/hv_hv.c optional hyperv
|
||||
dev/hyperv/vmbus/hv_ring_buffer.c optional hyperv
|
||||
dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c optional hyperv
|
||||
dev/kbd/kbd.c optional atkbd | sc | ukbd
|
||||
dev/kbd/kbd.c optional atkbd | sc | ukbd | vt
|
||||
dev/lindev/full.c optional lindev
|
||||
dev/lindev/lindev.c optional lindev
|
||||
dev/nfe/if_nfe.c optional nfe pci
|
||||
|
@ -62,7 +62,7 @@ crypto/blowfish/bf_enc.c optional crypto | ipsec
|
||||
crypto/des/des_enc.c optional crypto | ipsec | netsmb
|
||||
dev/fb/fb.c optional sc
|
||||
dev/hwpmc/hwpmc_arm.c optional hwpmc
|
||||
dev/kbd/kbd.c optional sc
|
||||
dev/kbd/kbd.c optional sc | vt
|
||||
dev/syscons/scgfbrndr.c optional sc
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvtb.c optional sc
|
||||
|
@ -249,7 +249,7 @@ dev/ipmi/ipmi_smbios.c optional ipmi
|
||||
dev/ipmi/ipmi_ssif.c optional ipmi smbus
|
||||
dev/ipmi/ipmi_pci.c optional ipmi pci
|
||||
dev/ipmi/ipmi_linux.c optional ipmi compat_linux
|
||||
dev/kbd/kbd.c optional atkbd | sc | ukbd
|
||||
dev/kbd/kbd.c optional atkbd | sc | ukbd | vt
|
||||
dev/le/if_le_isa.c optional le isa
|
||||
dev/lindev/full.c optional lindev
|
||||
dev/lindev/lindev.c optional lindev
|
||||
@ -293,6 +293,7 @@ dev/viawd/viawd.c optional viawd
|
||||
dev/vmware/vmxnet3/if_vmx.c optional vmx
|
||||
dev/acpica/acpi_if.m standard
|
||||
dev/acpi_support/acpi_wmi_if.m standard
|
||||
dev/vt/hw/xboxfb/xboxfb.c optional vt_xboxfb
|
||||
dev/wbwd/wbwd.c optional wbwd
|
||||
dev/wpi/if_wpi.c optional wpi
|
||||
dev/isci/isci.c optional isci
|
||||
|
@ -35,7 +35,7 @@ dev/iicbus/ad7417.c optional ad7417 powermac
|
||||
dev/iicbus/ds1631.c optional ds1631 powermac
|
||||
dev/iicbus/ds1775.c optional ds1775 powermac
|
||||
dev/iicbus/max6690.c optional max6690 powermac
|
||||
dev/kbd/kbd.c optional sc
|
||||
dev/kbd/kbd.c optional sc | vt
|
||||
dev/nand/nfc_fsl.c optional nand mpc85xx
|
||||
# ofw can be either aim or fdt: fdt case handled in files. aim only powerpc specific.
|
||||
dev/ofw/openfirm.c optional aim
|
||||
@ -65,6 +65,7 @@ dev/tsec/if_tsec.c optional tsec
|
||||
dev/tsec/if_tsec_fdt.c optional tsec fdt
|
||||
dev/uart/uart_cpu_powerpc.c optional uart
|
||||
dev/usb/controller/ehci_fsl.c optional ehci mpc85xx
|
||||
dev/vt/hw/ofwfb/ofwfb.c optional vt aim
|
||||
kern/kern_clocksource.c standard
|
||||
kern/subr_dummy_vdso_tc.c standard
|
||||
kern/syscalls.c optional ktr
|
||||
|
@ -39,7 +39,7 @@ dev/fb/fb.c optional sc
|
||||
dev/fb/gallant12x22.c optional sc
|
||||
dev/fb/machfb.c optional machfb sc
|
||||
dev/hwpmc/hwpmc_sparc64.c optional hwpmc
|
||||
dev/kbd/kbd.c optional atkbd | sc | ukbd
|
||||
dev/kbd/kbd.c optional atkbd | sc | ukbd | vt
|
||||
dev/le/if_le_lebuffer.c optional le sbus
|
||||
dev/le/if_le_ledma.c optional le sbus
|
||||
dev/le/lebuffer_sbus.c optional le sbus
|
||||
@ -59,7 +59,8 @@ dev/syscons/scgfbrndr.c optional sc
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvtb.c optional sc
|
||||
dev/uart/uart_cpu_sparc64.c optional uart
|
||||
dev/uart/uart_kbd_sun.c optional uart sc
|
||||
dev/uart/uart_kbd_sun.c optional uart sc | vt
|
||||
dev/vt/hw/ofwfb/ofwfb.c optional vt
|
||||
kern/kern_clocksource.c standard
|
||||
kern/subr_dummy_vdso_tc.c standard
|
||||
kern/syscalls.c optional ktr
|
||||
|
@ -340,7 +340,7 @@ CFLAGS+= ${CONF_CFLAGS}
|
||||
|
||||
MFILES?= dev/acpica/acpi_if.m dev/acpi_support/acpi_wmi_if.m \
|
||||
dev/agp/agp_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \
|
||||
dev/gpio/gpio_if.m dev/gpio/gpiobus_if.m \
|
||||
dev/fb/fb_if.m dev/gpio/gpio_if.m dev/gpio/gpiobus_if.m \
|
||||
dev/iicbus/iicbb_if.m dev/iicbus/iicbus_if.m \
|
||||
dev/mmc/mmcbr_if.m dev/mmc/mmcbus_if.m \
|
||||
dev/mii/miibus_if.m dev/mvs/mvs_if.m dev/ofw/ofw_bus_if.m \
|
||||
|
@ -731,8 +731,10 @@ SAFE_DEBUG opt_safe.h
|
||||
SAFE_NO_RNG opt_safe.h
|
||||
SAFE_RNDTEST opt_safe.h
|
||||
|
||||
# syscons options
|
||||
# syscons/vt options
|
||||
MAXCONS opt_syscons.h
|
||||
VT_FB_DEFAULT_WIDTH opt_syscons.h
|
||||
VT_FB_DEFAULT_HEIGHT opt_syscons.h
|
||||
SC_ALT_MOUSE_IMAGE opt_syscons.h
|
||||
SC_CUT_SPACES2TABS opt_syscons.h
|
||||
SC_CUT_SEPCHARS opt_syscons.h
|
||||
|
@ -36,6 +36,41 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/drm2/drm_fb_helper.h>
|
||||
#include <dev/drm2/drm_crtc_helper.h>
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
struct vt_kms_softc {
|
||||
struct drm_fb_helper *fb_helper;
|
||||
struct task fb_mode_task;
|
||||
};
|
||||
|
||||
static fb_enter_t vt_kms_postswitch;
|
||||
static void vt_restore_fbdev_mode(void *, int);
|
||||
|
||||
/* Call restore out of vt(9) locks. */
|
||||
static void
|
||||
vt_restore_fbdev_mode(void *arg, int pending)
|
||||
{
|
||||
struct drm_fb_helper *fb_helper;
|
||||
struct vt_kms_softc *sc;
|
||||
|
||||
sc = (struct vt_kms_softc *)arg;
|
||||
fb_helper = sc->fb_helper;
|
||||
sx_xlock(&fb_helper->dev->mode_config.mutex);
|
||||
drm_fb_helper_restore_fbdev_mode(fb_helper);
|
||||
sx_xunlock(&fb_helper->dev->mode_config.mutex);
|
||||
}
|
||||
|
||||
static int
|
||||
vt_kms_postswitch(void *arg)
|
||||
{
|
||||
struct vt_kms_softc *sc;
|
||||
|
||||
sc = (struct vt_kms_softc *)arg;
|
||||
taskqueue_enqueue_fast(taskqueue_thread, &sc->fb_mode_task);
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static DRM_LIST_HEAD(kernel_fb_helper_list);
|
||||
|
||||
/* simple single crtc case helper function */
|
||||
@ -216,6 +251,10 @@ static int
|
||||
fb_get_options(const char *connector_name, char **option)
|
||||
{
|
||||
|
||||
/*
|
||||
* TODO: store mode options pointer in ${option} for connector with
|
||||
* name ${connector_name}
|
||||
*/
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -892,11 +931,13 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
int new_fb = 0;
|
||||
int crtc_count = 0;
|
||||
int i;
|
||||
#if 0
|
||||
struct fb_info *info;
|
||||
#endif
|
||||
struct drm_fb_helper_surface_size sizes;
|
||||
int gamma_size = 0;
|
||||
#if defined(__FreeBSD__)
|
||||
struct vt_kms_softc *sc;
|
||||
device_t kdev;
|
||||
#endif
|
||||
|
||||
memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size));
|
||||
sizes.surface_depth = 24;
|
||||
@ -973,8 +1014,21 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
if (new_fb < 0)
|
||||
return new_fb;
|
||||
|
||||
#if 0
|
||||
#if defined(__FreeBSD__)
|
||||
sc = malloc(sizeof(struct vt_kms_softc), DRM_MEM_KMS,
|
||||
M_WAITOK | M_ZERO);
|
||||
sc->fb_helper = fb_helper;
|
||||
TASK_INIT(&sc->fb_mode_task, 0, vt_restore_fbdev_mode, sc);
|
||||
|
||||
info = fb_helper->fbdev;
|
||||
|
||||
info->fb_name = device_get_nameunit(fb_helper->dev->device);
|
||||
info->fb_depth = fb_helper->fb->bits_per_pixel;
|
||||
info->fb_height = fb_helper->fb->height;
|
||||
info->fb_width = fb_helper->fb->width;
|
||||
info->fb_stride = fb_helper->fb->pitches[0];
|
||||
info->fb_priv = sc;
|
||||
info->enter = &vt_kms_postswitch;
|
||||
#endif
|
||||
|
||||
/* set the fb pointer */
|
||||
@ -982,7 +1036,18 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined(__FreeBSD__)
|
||||
if (new_fb) {
|
||||
device_t fbd;
|
||||
int ret;
|
||||
|
||||
kdev = fb_helper->dev->device;
|
||||
fbd = device_add_child(kdev, "fbd", device_get_unit(kdev));
|
||||
ret = device_probe_and_attach(fbd);
|
||||
if (ret != 0)
|
||||
DRM_ERROR("Failed to attach fbd device: %d\n", ret);
|
||||
}
|
||||
#else
|
||||
if (new_fb) {
|
||||
info->var.pixclock = 0;
|
||||
if (register_framebuffer(info) < 0) {
|
||||
@ -1006,7 +1071,6 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
|
||||
if (new_fb)
|
||||
list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/fbio.h>
|
||||
|
||||
#if _BYTE_ORDER == _BIG_ENDIAN
|
||||
#define __BIG_ENDIAN 4321
|
||||
#else
|
||||
|
@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/drm2/drm_pciids.h>
|
||||
#include <dev/drm2/i915/intel_drv.h>
|
||||
|
||||
#include "fb_if.h"
|
||||
|
||||
/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
|
||||
static drm_pci_id_list_t i915_pciidlist[] = {
|
||||
i915_PCI_IDS
|
||||
@ -380,6 +382,25 @@ i915_attach(device_t kdev)
|
||||
return (drm_attach(kdev, i915_pciidlist));
|
||||
}
|
||||
|
||||
static struct fb_info *
|
||||
i915_fb_helper_getinfo(device_t kdev)
|
||||
{
|
||||
struct intel_fbdev *ifbdev;
|
||||
drm_i915_private_t *dev_priv;
|
||||
struct drm_device *dev;
|
||||
struct fb_info *info;
|
||||
|
||||
dev = device_get_softc(kdev);
|
||||
dev_priv = dev->dev_private;
|
||||
ifbdev = dev_priv->fbdev;
|
||||
if (ifbdev == NULL)
|
||||
return (NULL);
|
||||
|
||||
info = ifbdev->helper.fbdev;
|
||||
|
||||
return (info);
|
||||
}
|
||||
|
||||
const struct intel_device_info *
|
||||
i915_get_device_id(int device)
|
||||
{
|
||||
@ -400,6 +421,10 @@ static device_method_t i915_methods[] = {
|
||||
DEVMETHOD(device_suspend, i915_suspend),
|
||||
DEVMETHOD(device_resume, i915_resume),
|
||||
DEVMETHOD(device_detach, drm_detach),
|
||||
|
||||
/* Framebuffer service methods */
|
||||
DEVMETHOD(fb_getinfo, i915_fb_helper_getinfo),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
|
@ -41,8 +41,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||
struct drm_device *dev = ifbdev->helper.dev;
|
||||
#if 0
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct fb_info *info;
|
||||
#endif
|
||||
struct fb_info *info;
|
||||
struct drm_framebuffer *fb;
|
||||
struct drm_mode_fb_cmd2 mode_cmd;
|
||||
struct drm_i915_gem_object *obj;
|
||||
@ -86,6 +86,16 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||
}
|
||||
|
||||
info->par = ifbdev;
|
||||
#else
|
||||
info = malloc(sizeof(struct fb_info), DRM_MEM_KMS, M_WAITOK | M_ZERO);
|
||||
info->fb_size = size;
|
||||
info->fb_bpp = sizes->surface_bpp;
|
||||
info->fb_width = sizes->fb_width;
|
||||
info->fb_height = sizes->fb_height;
|
||||
info->fb_pbase = dev->agp->base + obj->gtt_offset;
|
||||
info->fb_vbase = (vm_offset_t)pmap_mapdev_attr(info->fb_pbase, size,
|
||||
PAT_WRITE_COMBINING);
|
||||
|
||||
#endif
|
||||
|
||||
ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
|
||||
@ -95,8 +105,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||
fb = &ifbdev->ifb.base;
|
||||
|
||||
ifbdev->helper.fb = fb;
|
||||
#if 0
|
||||
ifbdev->helper.fbdev = info;
|
||||
#if 0
|
||||
|
||||
strcpy(info->fix.id, "inteldrmfb");
|
||||
|
||||
@ -135,9 +145,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||
|
||||
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
|
||||
#endif
|
||||
|
||||
DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
|
||||
fb->width, fb->height,
|
||||
DRM_DEBUG_KMS("allocated %dx%d (s %dbits) fb: 0x%08x, bo %p\n",
|
||||
fb->width, fb->height, fb->depth,
|
||||
obj->gtt_offset, obj);
|
||||
|
||||
DRM_UNLOCK(dev);
|
||||
|
@ -2041,6 +2041,9 @@ void radeon_pm_acpi_event_handler(struct radeon_device *rdev);
|
||||
int radeon_ttm_init(struct radeon_device *rdev);
|
||||
void radeon_ttm_fini(struct radeon_device *rdev);
|
||||
|
||||
/* radeon_fb.c */
|
||||
struct fb_info * radeon_fb_helper_getinfo(device_t kdev);
|
||||
|
||||
/* r600.c */
|
||||
int r600_ih_ring_alloc(struct radeon_device *rdev);
|
||||
void r600_ih_ring_fini(struct radeon_device *rdev);
|
||||
|
@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/drm2/drm_pciids.h>
|
||||
|
||||
#include "fb_if.h"
|
||||
|
||||
/*
|
||||
* KMS wrapper.
|
||||
@ -495,6 +496,8 @@ radeon_resume(device_t kdev)
|
||||
return (-ret);
|
||||
}
|
||||
|
||||
extern struct fb_info * radeon_fb_helper_getinfo(device_t kdev);
|
||||
|
||||
static device_method_t radeon_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, radeon_probe),
|
||||
@ -502,6 +505,10 @@ static device_method_t radeon_methods[] = {
|
||||
DEVMETHOD(device_suspend, radeon_suspend),
|
||||
DEVMETHOD(device_resume, radeon_resume),
|
||||
DEVMETHOD(device_detach, drm_detach),
|
||||
|
||||
/* Framebuffer service methods */
|
||||
DEVMETHOD(fb_getinfo, radeon_fb_helper_getinfo),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/_inttypes.h>
|
||||
|
||||
#include <dev/drm2/drmP.h>
|
||||
#include <dev/drm2/drm_crtc.h>
|
||||
#include <dev/drm2/drm_crtc_helper.h>
|
||||
@ -46,7 +48,7 @@ struct radeon_fbdev {
|
||||
struct radeon_device *rdev;
|
||||
};
|
||||
|
||||
#ifdef DUMBBELL_WIP
|
||||
#if defined(__linux__)
|
||||
static struct fb_ops radeonfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_check_var = drm_fb_helper_check_var,
|
||||
@ -60,7 +62,7 @@ static struct fb_ops radeonfb_ops = {
|
||||
.fb_debug_enter = drm_fb_helper_debug_enter,
|
||||
.fb_debug_leave = drm_fb_helper_debug_leave,
|
||||
};
|
||||
#endif /* DUMBBELL_WIP */
|
||||
#endif
|
||||
|
||||
|
||||
int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
|
||||
@ -191,20 +193,13 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
|
||||
struct drm_fb_helper_surface_size *sizes)
|
||||
{
|
||||
struct radeon_device *rdev = rfbdev->rdev;
|
||||
#ifdef DUMBBELL_WIP
|
||||
struct fb_info *info;
|
||||
#endif /* DUMBBELL_WIP */
|
||||
struct drm_framebuffer *fb = NULL;
|
||||
struct drm_mode_fb_cmd2 mode_cmd;
|
||||
struct drm_gem_object *gobj = NULL;
|
||||
struct radeon_bo *rbo = NULL;
|
||||
#ifdef DUMBBELL_WIP
|
||||
device_t device = rdev->dev;
|
||||
#endif /* DUMBBELL_WIP */
|
||||
int ret;
|
||||
#ifdef DUMBBELL_WIP
|
||||
unsigned long tmp;
|
||||
#endif /* DUMBBELL_WIP */
|
||||
|
||||
mode_cmd.width = sizes->surface_width;
|
||||
mode_cmd.height = sizes->surface_height;
|
||||
@ -224,16 +219,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
|
||||
|
||||
rbo = gem_to_radeon_bo(gobj);
|
||||
|
||||
#ifdef DUMBBELL_WIP
|
||||
/* okay we have an object now allocate the framebuffer */
|
||||
info = framebuffer_alloc(0, device);
|
||||
if (info == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unref;
|
||||
}
|
||||
|
||||
info->par = rfbdev;
|
||||
#endif /* DUMBBELL_WIP */
|
||||
info = malloc(sizeof(*info), DRM_MEM_KMS, M_WAITOK | M_ZERO);
|
||||
|
||||
ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
|
||||
if (ret) {
|
||||
@ -245,61 +231,29 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
|
||||
|
||||
/* setup helper */
|
||||
rfbdev->helper.fb = fb;
|
||||
#ifdef DUMBBELL_WIP
|
||||
rfbdev->helper.fbdev = info;
|
||||
|
||||
memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo));
|
||||
|
||||
strcpy(info->fix.id, "radeondrmfb");
|
||||
|
||||
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
|
||||
|
||||
info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
|
||||
info->fbops = &radeonfb_ops;
|
||||
memset(rbo->kptr, 0x0, radeon_bo_size(rbo));
|
||||
|
||||
tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start;
|
||||
info->fix.smem_start = rdev->mc.aper_base + tmp;
|
||||
info->fix.smem_len = radeon_bo_size(rbo);
|
||||
info->screen_base = rbo->kptr;
|
||||
info->screen_size = radeon_bo_size(rbo);
|
||||
info->fb_size = radeon_bo_size(rbo);
|
||||
info->fb_bpp = sizes->surface_bpp;
|
||||
info->fb_width = sizes->surface_width;
|
||||
info->fb_height = sizes->surface_height;
|
||||
info->fb_pbase = rdev->mc.aper_base + tmp;
|
||||
info->fb_vbase = (vm_offset_t)rbo->kptr;
|
||||
|
||||
drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
|
||||
|
||||
/* setup aperture base/size for vesafb takeover */
|
||||
info->apertures = alloc_apertures(1);
|
||||
if (!info->apertures) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unref;
|
||||
}
|
||||
info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
|
||||
info->apertures->ranges[0].size = rdev->mc.aper_size;
|
||||
|
||||
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
|
||||
|
||||
if (info->screen_base == NULL) {
|
||||
ret = -ENOSPC;
|
||||
goto out_unref;
|
||||
}
|
||||
|
||||
ret = fb_alloc_cmap(&info->cmap, 256, 0);
|
||||
if (ret) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unref;
|
||||
}
|
||||
|
||||
DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start);
|
||||
DRM_INFO("fb mappable at 0x%" PRIXPTR "\n", info->fb_pbase);
|
||||
DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base);
|
||||
DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo));
|
||||
DRM_INFO("fb depth is %d\n", fb->depth);
|
||||
DRM_INFO(" pitch is %d\n", fb->pitches[0]);
|
||||
|
||||
vga_switcheroo_client_fb_set(rdev->ddev->pdev, info);
|
||||
#endif /* DUMBBELL_WIP */
|
||||
return 0;
|
||||
|
||||
out_unref:
|
||||
if (rbo) {
|
||||
|
||||
/* TODO? dumbbell@ */
|
||||
}
|
||||
if (fb && ret) {
|
||||
drm_gem_object_unreference(gobj);
|
||||
@ -332,21 +286,13 @@ void radeon_fb_output_poll_changed(struct radeon_device *rdev)
|
||||
|
||||
static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
|
||||
{
|
||||
#ifdef DUMBBELL_WIP
|
||||
struct fb_info *info;
|
||||
#endif /* DUMBBELL_WIP */
|
||||
struct radeon_framebuffer *rfb = &rfbdev->rfb;
|
||||
|
||||
#ifdef DUMBBELL_WIP
|
||||
if (rfbdev->helper.fbdev) {
|
||||
info = rfbdev->helper.fbdev;
|
||||
|
||||
unregister_framebuffer(info);
|
||||
if (info->cmap.len)
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
framebuffer_release(info);
|
||||
free(info, DRM_MEM_KMS);
|
||||
}
|
||||
#endif /* DUMBBELL_WIP */
|
||||
|
||||
if (rfb->obj) {
|
||||
DRM_UNLOCK(dev); /* Work around lock recursion. dumbbell@ */
|
||||
@ -431,3 +377,22 @@ bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct fb_info *
|
||||
radeon_fb_helper_getinfo(device_t kdev)
|
||||
{
|
||||
struct drm_device *dev;
|
||||
struct radeon_device *rdev;
|
||||
struct radeon_fbdev *rfbdev;
|
||||
struct fb_info *info;
|
||||
|
||||
dev = device_get_softc(kdev);
|
||||
rdev = dev->dev_private;
|
||||
rfbdev = rdev->mode_info.rfbdev;
|
||||
if (rfbdev == NULL)
|
||||
return (NULL);
|
||||
|
||||
info = rfbdev->helper.fbdev;
|
||||
|
||||
return (info);
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
|
||||
(rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index))
|
||||
return;
|
||||
|
||||
DRM_LOCK(rdev->ddev);
|
||||
//DRM_LOCK(rdev->ddev); XXX Recursion, already locked in drm_attach/drm_load -- dumbbell@
|
||||
sx_xlock(&rdev->pm.mclk_lock);
|
||||
sx_xlock(&rdev->ring_lock);
|
||||
|
||||
@ -263,7 +263,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
|
||||
/* needs a GPU reset dont reset here */
|
||||
sx_xunlock(&rdev->ring_lock);
|
||||
sx_xunlock(&rdev->pm.mclk_lock);
|
||||
DRM_UNLOCK(rdev->ddev);
|
||||
//DRM_UNLOCK(rdev->ddev); XXX Recursion, already locked in drm_attach/drm_load -- dumbbell@
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -299,7 +299,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
|
||||
|
||||
sx_xunlock(&rdev->ring_lock);
|
||||
sx_xunlock(&rdev->pm.mclk_lock);
|
||||
DRM_UNLOCK(rdev->ddev);
|
||||
//DRM_UNLOCK(rdev->ddev); XXX Recursion, already locked in drm_attach/drm_load -- dumbbell@
|
||||
}
|
||||
|
||||
static void radeon_pm_print_states(struct radeon_device *rdev)
|
||||
|
13
sys/dev/fb/fb_if.m
Normal file
13
sys/dev/fb/fb_if.m
Normal file
@ -0,0 +1,13 @@
|
||||
#include <sys/bus.h>
|
||||
#include <sys/fbio.h>
|
||||
|
||||
INTERFACE fb;
|
||||
|
||||
METHOD int pin_max {
|
||||
device_t dev;
|
||||
int *npins;
|
||||
};
|
||||
|
||||
METHOD struct fb_info * getinfo {
|
||||
device_t dev;
|
||||
};
|
467
sys/dev/fb/fbd.c
Normal file
467
sys/dev/fb/fbd.c
Normal file
@ -0,0 +1,467 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Aleksandr Rybalko under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/* Generic framebuffer */
|
||||
/* TODO unlink from VT(9) */
|
||||
/* TODO done normal /dev/fb methods */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/fbio.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
#include <dev/vt/hw/fb/vt_fb.h>
|
||||
|
||||
#include "fb_if.h"
|
||||
|
||||
LIST_HEAD(fb_list_head_t, fb_list_entry) fb_list_head =
|
||||
LIST_HEAD_INITIALIZER(fb_list_head);
|
||||
struct fb_list_entry {
|
||||
struct fb_info *fb_info;
|
||||
struct cdev *fb_si;
|
||||
LIST_ENTRY(fb_list_entry) fb_list;
|
||||
};
|
||||
|
||||
struct fbd_softc {
|
||||
device_t sc_dev;
|
||||
struct fb_info *sc_info;
|
||||
};
|
||||
|
||||
static void fbd_evh_init(void *);
|
||||
/* SI_ORDER_SECOND, just after EVENTHANDLERs initialized. */
|
||||
SYSINIT(fbd_evh_init, SI_SUB_CONFIGURE, SI_ORDER_SECOND, fbd_evh_init, NULL);
|
||||
|
||||
static d_open_t fb_open;
|
||||
static d_close_t fb_close;
|
||||
static d_read_t fb_read;
|
||||
static d_write_t fb_write;
|
||||
static d_ioctl_t fb_ioctl;
|
||||
static d_mmap_t fb_mmap;
|
||||
|
||||
static struct cdevsw fb_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_flags = D_NEEDGIANT,
|
||||
.d_open = fb_open,
|
||||
.d_close = fb_close,
|
||||
.d_read = fb_read,
|
||||
.d_write = fb_write,
|
||||
.d_ioctl = fb_ioctl,
|
||||
.d_mmap = fb_mmap,
|
||||
.d_name = "fb",
|
||||
};
|
||||
|
||||
static int framebuffer_dev_unit = 0;
|
||||
|
||||
static int
|
||||
fb_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fb_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fb_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
||||
struct thread *td)
|
||||
{
|
||||
struct fb_info *info;
|
||||
int error;
|
||||
|
||||
error = 0;
|
||||
info = dev->si_drv1;
|
||||
|
||||
switch (cmd) {
|
||||
case FBIOGTYPE:
|
||||
bcopy(info, (struct fbtype *)data, sizeof(struct fbtype));
|
||||
break;
|
||||
|
||||
case FBIO_GETWINORG: /* get frame buffer window origin */
|
||||
*(u_int *)data = 0;
|
||||
break;
|
||||
|
||||
case FBIO_GETDISPSTART: /* get display start address */
|
||||
((video_display_start_t *)data)->x = 0;
|
||||
((video_display_start_t *)data)->y = 0;
|
||||
break;
|
||||
|
||||
case FBIO_GETLINEWIDTH: /* get scan line width in bytes */
|
||||
*(u_int *)data = info->fb_stride;
|
||||
break;
|
||||
|
||||
case FBIO_BLANK: /* blank display */
|
||||
error = 0; /* TODO */
|
||||
break;
|
||||
|
||||
default:
|
||||
error = ENOIOCTL;
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
fb_read(struct cdev *dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
|
||||
return (0); /* XXX nothing to read, yet */
|
||||
}
|
||||
|
||||
static int
|
||||
fb_write(struct cdev *dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
|
||||
return (0); /* XXX nothing written */
|
||||
}
|
||||
|
||||
static int
|
||||
fb_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot,
|
||||
vm_memattr_t *memattr)
|
||||
{
|
||||
struct fb_info *info;
|
||||
|
||||
info = dev->si_drv1;
|
||||
if (offset < info->fb_size) {
|
||||
*paddr = info->fb_pbase + offset;
|
||||
return (0);
|
||||
}
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vt_fb_mem_wr1(struct fb_info *sc, uint32_t o, uint8_t v)
|
||||
{
|
||||
|
||||
KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o));
|
||||
*(uint8_t *)(sc->fb_vbase + o) = v;
|
||||
}
|
||||
|
||||
static void
|
||||
vt_fb_mem_wr2(struct fb_info *sc, uint32_t o, uint16_t v)
|
||||
{
|
||||
|
||||
KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o));
|
||||
*(uint16_t *)(sc->fb_vbase + o) = v;
|
||||
}
|
||||
|
||||
static void
|
||||
vt_fb_mem_wr4(struct fb_info *sc, uint32_t o, uint32_t v)
|
||||
{
|
||||
|
||||
KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o));
|
||||
*(uint32_t *)(sc->fb_vbase + o) = v;
|
||||
}
|
||||
|
||||
static void
|
||||
vt_fb_mem_copy(struct fb_info *sc, uint32_t offset_to, uint32_t offset_from,
|
||||
uint32_t size)
|
||||
{
|
||||
|
||||
memmove((void *)(sc->fb_vbase + offset_to), (void *)(sc->fb_vbase +
|
||||
offset_from), size);
|
||||
}
|
||||
|
||||
static void
|
||||
vt_fb_indir_wr1(struct fb_info *sc, uint32_t o, uint8_t v)
|
||||
{
|
||||
|
||||
KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o));
|
||||
sc->fb_write(sc->fb_priv, o, &v, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
vt_fb_indir_wr2(struct fb_info *sc, uint32_t o, uint16_t v)
|
||||
{
|
||||
|
||||
KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o));
|
||||
sc->fb_write(sc->fb_priv, o, &v, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
vt_fb_indir_wr4(struct fb_info *sc, uint32_t o, uint32_t v)
|
||||
{
|
||||
|
||||
KASSERT((o < sc->fb_size), ("Offset %#08x out of fb size", o));
|
||||
sc->fb_write(sc->fb_priv, o, &v, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
vt_fb_indir_copy(struct fb_info *sc, uint32_t offset_to, uint32_t offset_from,
|
||||
uint32_t size)
|
||||
{
|
||||
|
||||
sc->copy(sc->fb_priv, offset_to, offset_from, size);
|
||||
}
|
||||
|
||||
int
|
||||
fb_probe(struct fb_info *info)
|
||||
{
|
||||
|
||||
if (info->fb_size == 0)
|
||||
return (ENXIO);
|
||||
|
||||
if (info->fb_write != NULL) {
|
||||
if (info->fb_write == NULL) {
|
||||
return (EINVAL);
|
||||
}
|
||||
info->fb_flags |= FB_FLAG_NOMMAP;
|
||||
info->wr1 = &vt_fb_indir_wr1;
|
||||
info->wr2 = &vt_fb_indir_wr2;
|
||||
info->wr4 = &vt_fb_indir_wr4;
|
||||
info->copy = &vt_fb_indir_copy;
|
||||
} else if (info->fb_vbase != 0) {
|
||||
if (info->fb_pbase == 0)
|
||||
info->fb_flags |= FB_FLAG_NOMMAP;
|
||||
info->wr1 = &vt_fb_mem_wr1;
|
||||
info->wr2 = &vt_fb_mem_wr2;
|
||||
info->wr4 = &vt_fb_mem_wr4;
|
||||
info->copy = &vt_fb_mem_copy;
|
||||
} else
|
||||
return (ENXIO);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
fb_init(struct fb_list_entry *entry, int unit)
|
||||
{
|
||||
struct fb_info *info;
|
||||
|
||||
info = entry->fb_info;
|
||||
entry->fb_si = make_dev(&fb_cdevsw, unit, UID_ROOT, GID_WHEEL,
|
||||
0600, "fb%d", unit);
|
||||
entry->fb_si->si_drv1 = info;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
fbd_list()
|
||||
{
|
||||
struct fb_list_entry *entry;
|
||||
|
||||
if (LIST_EMPTY(&fb_list_head))
|
||||
return (ENOENT);
|
||||
|
||||
LIST_FOREACH(entry, &fb_list_head, fb_list) {
|
||||
printf("FB %s @%p\n", entry->fb_info->fb_name,
|
||||
(void *)entry->fb_info->fb_pbase);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct fb_list_entry *
|
||||
fbd_find(struct fb_info* info)
|
||||
{
|
||||
struct fb_list_entry *entry, *tmp;
|
||||
|
||||
LIST_FOREACH_SAFE(entry, &fb_list_head, fb_list, tmp) {
|
||||
if (entry->fb_info == info) {
|
||||
return (entry);
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
fbd_register(struct fb_info* info)
|
||||
{
|
||||
struct fb_list_entry *entry;
|
||||
int err, first;
|
||||
|
||||
first = 0;
|
||||
if (LIST_EMPTY(&fb_list_head))
|
||||
first++;
|
||||
|
||||
entry = fbd_find(info);
|
||||
if (entry != NULL) {
|
||||
/* XXX Update framebuffer params */
|
||||
return (0);
|
||||
}
|
||||
|
||||
err = fb_probe(info);
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
entry = malloc(sizeof(struct fb_list_entry), M_DEVBUF, M_WAITOK|M_ZERO);
|
||||
entry->fb_info = info;
|
||||
|
||||
LIST_INSERT_HEAD(&fb_list_head, entry, fb_list);
|
||||
|
||||
err = fb_init(entry, framebuffer_dev_unit++);
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
if (first)
|
||||
vt_fb_attach(info);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
fbd_unregister(struct fb_info* info)
|
||||
{
|
||||
struct fb_list_entry *entry, *tmp;
|
||||
|
||||
LIST_FOREACH_SAFE(entry, &fb_list_head, fb_list, tmp) {
|
||||
if (entry->fb_info == info) {
|
||||
LIST_REMOVE(entry, fb_list);
|
||||
free(entry, M_DEVBUF);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
static void
|
||||
register_fb_wrap(void *arg, void *ptr)
|
||||
{
|
||||
|
||||
fbd_register((struct fb_info *)ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
unregister_fb_wrap(void *arg, void *ptr)
|
||||
{
|
||||
|
||||
fbd_unregister((struct fb_info *)ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
fbd_evh_init(void *ctx)
|
||||
{
|
||||
|
||||
EVENTHANDLER_REGISTER(register_framebuffer, register_fb_wrap, NULL,
|
||||
EVENTHANDLER_PRI_ANY);
|
||||
EVENTHANDLER_REGISTER(unregister_framebuffer, unregister_fb_wrap, NULL,
|
||||
EVENTHANDLER_PRI_ANY);
|
||||
}
|
||||
|
||||
/* Newbus methods. */
|
||||
static int
|
||||
fbd_probe(device_t dev)
|
||||
{
|
||||
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
}
|
||||
|
||||
static int
|
||||
fbd_attach(device_t dev)
|
||||
{
|
||||
struct fbd_softc *sc;
|
||||
int err;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
sc->sc_dev = dev;
|
||||
sc->sc_info = FB_GETINFO(device_get_parent(dev));
|
||||
if (sc->sc_info == NULL)
|
||||
return (ENXIO);
|
||||
err = fbd_register(sc->sc_info);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
fbd_detach(device_t dev)
|
||||
{
|
||||
struct fbd_softc *sc;
|
||||
int err;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
err = fbd_unregister(sc->sc_info);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
static int
|
||||
fbd_suspend(device_t dev)
|
||||
{
|
||||
|
||||
vt_fb_suspend();
|
||||
return (bus_generic_suspend(dev));
|
||||
}
|
||||
|
||||
static int
|
||||
fbd_resume(device_t dev)
|
||||
{
|
||||
|
||||
vt_fb_resume();
|
||||
return (bus_generic_resume(dev));
|
||||
}
|
||||
|
||||
static device_method_t fbd_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, fbd_probe),
|
||||
DEVMETHOD(device_attach, fbd_attach),
|
||||
DEVMETHOD(device_detach, fbd_detach),
|
||||
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
DEVMETHOD(device_suspend, fbd_suspend),
|
||||
DEVMETHOD(device_resume, fbd_resume),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
driver_t fbd_driver = {
|
||||
"fbd",
|
||||
fbd_methods,
|
||||
sizeof(struct fbd_softc)
|
||||
};
|
||||
|
||||
devclass_t fbd_devclass;
|
||||
|
||||
DRIVER_MODULE(fbd, fb, fbd_driver, fbd_devclass, 0, 0);
|
||||
DRIVER_MODULE(fbd, drmn, fbd_driver, fbd_devclass, 0, 0);
|
||||
MODULE_VERSION(fbd, 1);
|
||||
|
80
sys/dev/vt/colors/vt_termcolors.c
Normal file
80
sys/dev/vt/colors/vt_termcolors.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Aleksandr Rybalko under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/vt/colors/vt_termcolors.h>
|
||||
|
||||
static struct {
|
||||
unsigned char r; /* Red percentage value. */
|
||||
unsigned char g; /* Green percentage value. */
|
||||
unsigned char b; /* Blue percentage value. */
|
||||
} color_def[16] = {
|
||||
{0, 0, 0}, /* black */
|
||||
{0, 0, 50}, /* dark blue */
|
||||
{0, 50, 0}, /* dark green */
|
||||
{0, 50, 50}, /* dark cyan */
|
||||
{50, 0, 0}, /* dark red */
|
||||
{50, 0, 50}, /* dark magenta */
|
||||
{50, 50, 0}, /* brown */
|
||||
{75, 75, 75}, /* light gray */
|
||||
{50, 50, 50}, /* dark gray */
|
||||
{0, 0, 100}, /* light blue */
|
||||
{0, 100, 0}, /* light green */
|
||||
{0, 100, 100}, /* light cyan */
|
||||
{100, 0, 0}, /* light red */
|
||||
{100, 0, 100}, /* light magenta */
|
||||
{100, 100, 0}, /* yellow */
|
||||
{100, 100, 100}, /* white */
|
||||
};
|
||||
|
||||
int
|
||||
vt_generate_vga_palette(uint32_t *palette, int format, uint32_t rmax, int roffset,
|
||||
uint32_t gmax, int goffset, uint32_t bmax, int boffset)
|
||||
{
|
||||
int i;
|
||||
|
||||
#define CF(_f, _i) ((_f ## max * color_def[(_i)]._f / 100) << _f ## offset)
|
||||
for (i = 0; i < 16; i++) {
|
||||
switch (format) {
|
||||
case COLOR_FORMAT_VGA:
|
||||
palette[i] = i;
|
||||
break;
|
||||
case COLOR_FORMAT_RGB:
|
||||
palette[i] = CF(r, i) | CF(g, i) | CF(b, i);
|
||||
break;
|
||||
default:
|
||||
return (ENODEV);
|
||||
}
|
||||
}
|
||||
#undef CF
|
||||
return (0);
|
||||
}
|
50
sys/dev/vt/colors/vt_termcolors.h
Normal file
50
sys/dev/vt/colors/vt_termcolors.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Aleksandr Rybalko under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
enum vt_color_format {
|
||||
COLOR_FORMAT_BW = 0,
|
||||
COLOR_FORMAT_GRAY,
|
||||
COLOR_FORMAT_VGA, /* Color Index. */
|
||||
COLOR_FORMAT_RGB,
|
||||
COLOR_FORMAT_ARGB,
|
||||
COLOR_FORMAT_CMYK,
|
||||
COLOR_FORMAT_HSL,
|
||||
COLOR_FORMAT_YUV,
|
||||
COLOR_FORMAT_YCbCr,
|
||||
COLOR_FORMAT_YPbPr,
|
||||
|
||||
COLOR_FORMAT_MAX = 15,
|
||||
};
|
||||
|
||||
/* Helper to fill color map used by driver */
|
||||
int vt_generate_vga_palette(uint32_t *palette, int format, uint32_t rmax,
|
||||
int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset);
|
||||
|
2202
sys/dev/vt/font/vt_font_default.c
Normal file
2202
sys/dev/vt/font/vt_font_default.c
Normal file
File diff suppressed because it is too large
Load Diff
68
sys/dev/vt/font/vt_mouse_cursor.c
Normal file
68
sys/dev/vt/font/vt_mouse_cursor.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Aleksandr Rybalko under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
|
||||
struct mouse_cursor vt_default_mouse_pointer = {
|
||||
.map = {
|
||||
0x00, /* "__ " */
|
||||
0x40, /* "_*_ " */
|
||||
0x60, /* "_**_ " */
|
||||
0x70, /* "_***_ " */
|
||||
0x78, /* "_****_ " */
|
||||
0x7c, /* "_*****_ " */
|
||||
0x7e, /* "_******_" */
|
||||
0x68, /* "_**_****" */
|
||||
0x4c, /* "_*__**__" */
|
||||
0x0c, /* " _ _**_ " */
|
||||
0x06, /* " _**_" */
|
||||
0x06, /* " _**_" */
|
||||
0x00, /* " ____" */
|
||||
},
|
||||
.mask = {
|
||||
0xc0, /* "__ " */
|
||||
0xe0, /* "___ " */
|
||||
0xf0, /* "____ " */
|
||||
0xf8, /* "_____ " */
|
||||
0xfc, /* "______ " */
|
||||
0xfe, /* "_______ " */
|
||||
0xff, /* "________" */
|
||||
0xff, /* "________" */
|
||||
0xff, /* "________" */
|
||||
0x1e, /* " ____ " */
|
||||
0x0f, /* " ____" */
|
||||
0x0f, /* " ____" */
|
||||
0x0f, /* " ____" */
|
||||
},
|
||||
.w = 8,
|
||||
.h = 13,
|
||||
};
|
278
sys/dev/vt/hw/fb/vt_early_fb.c
Normal file
278
sys/dev/vt/hw/fb/vt_early_fb.c
Normal file
@ -0,0 +1,278 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Aleksandr Rybalko under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/fbio.h>
|
||||
|
||||
#include "opt_platform.h"
|
||||
|
||||
#ifdef FDT
|
||||
#include <dev/fdt/fdt_common.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#include <dev/ofw/ofw_pci.h>
|
||||
#endif
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
#include <dev/vt/hw/fb/vt_fb.h>
|
||||
#include <dev/vt/colors/vt_termcolors.h>
|
||||
|
||||
static vd_init_t vt_efb_init;
|
||||
|
||||
static struct vt_driver vt_fb_early_driver = {
|
||||
.vd_init = vt_efb_init,
|
||||
.vd_blank = vt_fb_blank,
|
||||
.vd_bitbltchr = vt_fb_bitbltchr,
|
||||
.vd_priority = VD_PRIORITY_GENERIC,
|
||||
};
|
||||
|
||||
static struct fb_info info;
|
||||
VT_CONSDEV_DECLARE(vt_fb_early_driver,
|
||||
MAX(80, PIXEL_WIDTH(VT_FB_DEFAULT_WIDTH)),
|
||||
MAX(25, PIXEL_HEIGHT(VT_FB_DEFAULT_HEIGHT)), &info);
|
||||
|
||||
static void
|
||||
#ifdef FDT
|
||||
vt_efb_initialize(struct fb_info *info, phandle_t node)
|
||||
#else
|
||||
vt_efb_initialize(struct fb_info *info)
|
||||
#endif
|
||||
{
|
||||
#ifdef FDT
|
||||
char name[64];
|
||||
cell_t retval;
|
||||
ihandle_t ih;
|
||||
int i;
|
||||
|
||||
/* Open display device, thereby initializing it */
|
||||
memset(name, 0, sizeof(name));
|
||||
OF_package_to_path(node, name, sizeof(name));
|
||||
ih = OF_open(name);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up the color map
|
||||
*/
|
||||
switch (info->fb_depth) {
|
||||
case 8:
|
||||
vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB,
|
||||
0x7, 5, 0x7, 2, 0x3, 0);
|
||||
break;
|
||||
case 15:
|
||||
vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB,
|
||||
0x1f, 10, 0x1f, 5, 0x1f, 0);
|
||||
break;
|
||||
case 16:
|
||||
vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB,
|
||||
0x1f, 11, 0x3f, 5, 0x1f, 0);
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
vt_generate_vga_palette(info->fb_cmap,
|
||||
COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0);
|
||||
#else
|
||||
vt_generate_vga_palette(info->fb_cmap,
|
||||
COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16);
|
||||
#endif
|
||||
#ifdef FDT
|
||||
for (i = 0; i < 16; i++) {
|
||||
OF_call_method("color!", ih, 4, 1,
|
||||
(cell_t)((info->fb_cmap[i] >> 16) & 0xff),
|
||||
(cell_t)((info->fb_cmap[i] >> 8) & 0xff),
|
||||
(cell_t)((info->fb_cmap[i] >> 0) & 0xff),
|
||||
(cell_t)i, &retval);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Unknown color space fb_depth %d", info->fb_depth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vt_efb_init(struct vt_device *vd)
|
||||
{
|
||||
struct ofw_pci_register pciaddrs[8];
|
||||
struct fb_info *info;
|
||||
int i, len, n_pciaddrs;
|
||||
phandle_t chosen, node;
|
||||
ihandle_t stdout;
|
||||
char type[64];
|
||||
|
||||
info = vd->vd_softc;
|
||||
|
||||
chosen = OF_finddevice("/chosen");
|
||||
OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
|
||||
node = OF_instance_to_package(stdout);
|
||||
if (node == -1) {
|
||||
/*
|
||||
* The "/chosen/stdout" does not exist try
|
||||
* using "screen" directly.
|
||||
*/
|
||||
node = OF_finddevice("screen");
|
||||
}
|
||||
OF_getprop(node, "device_type", type, sizeof(type));
|
||||
if (strcmp(type, "display") != 0)
|
||||
return (CN_DEAD);
|
||||
|
||||
#define GET(name, var) \
|
||||
if (OF_getproplen(node, (name)) != sizeof(info->fb_##var)) \
|
||||
return (CN_DEAD); \
|
||||
OF_getencprop(node, (name), &info->fb_##var, sizeof(info->fb_##var)); \
|
||||
if (info->fb_##var == 0) \
|
||||
return (CN_DEAD);
|
||||
|
||||
GET("height", height)
|
||||
GET("width", width)
|
||||
GET("depth", depth)
|
||||
GET("linebytes", stride)
|
||||
#undef GET
|
||||
|
||||
info->fb_size = info->fb_height * info->fb_stride;
|
||||
|
||||
/*
|
||||
* Get the PCI addresses of the adapter, if present. The node may be the
|
||||
* child of the PCI device: in that case, try the parent for
|
||||
* the assigned-addresses property.
|
||||
*/
|
||||
len = OF_getprop(node, "assigned-addresses", pciaddrs,
|
||||
sizeof(pciaddrs));
|
||||
if (len == -1) {
|
||||
len = OF_getprop(OF_parent(node), "assigned-addresses",
|
||||
pciaddrs, sizeof(pciaddrs));
|
||||
}
|
||||
if (len == -1)
|
||||
len = 0;
|
||||
n_pciaddrs = len / sizeof(struct ofw_pci_register);
|
||||
|
||||
/*
|
||||
* Grab the physical address of the framebuffer, and then map it
|
||||
* into our memory space. If the MMU is not yet up, it will be
|
||||
* remapped for us when relocation turns on.
|
||||
*/
|
||||
if (OF_getproplen(node, "address") == sizeof(info->fb_pbase)) {
|
||||
/* XXX We assume #address-cells is 1 at this point. */
|
||||
OF_getencprop(node, "address", &info->fb_pbase,
|
||||
sizeof(info->fb_pbase));
|
||||
|
||||
#if defined(__powerpc__)
|
||||
sc->sc_memt = &bs_be_tag;
|
||||
bus_space_map(sc->sc_memt, info->fb_pbase, info->fb_size,
|
||||
BUS_SPACE_MAP_PREFETCHABLE, &info->fb_vbase);
|
||||
#elif defined(__sparc64__)
|
||||
OF_decode_addr(node, 0, &space, &phys);
|
||||
sc->sc_memt = &vt_efb_memt[0];
|
||||
info->addr = sparc64_fake_bustag(space, fb_phys, sc->sc_memt);
|
||||
#else
|
||||
bus_space_map(fdtbus_bs_tag, info->fb_pbase, info->fb_size,
|
||||
BUS_SPACE_MAP_PREFETCHABLE,
|
||||
(bus_space_handle_t *)&info->fb_vbase);
|
||||
#endif
|
||||
} else {
|
||||
/*
|
||||
* Some IBM systems don't have an address property. Try to
|
||||
* guess the framebuffer region from the assigned addresses.
|
||||
* This is ugly, but there doesn't seem to be an alternative.
|
||||
* Linux does the same thing.
|
||||
*/
|
||||
|
||||
info->fb_pbase = n_pciaddrs;
|
||||
for (i = 0; i < n_pciaddrs; i++) {
|
||||
/* If it is too small, not the framebuffer */
|
||||
if (pciaddrs[i].size_lo < info->fb_size)
|
||||
continue;
|
||||
/* If it is not memory, it isn't either */
|
||||
if (!(pciaddrs[i].phys_hi &
|
||||
OFW_PCI_PHYS_HI_SPACE_MEM32))
|
||||
continue;
|
||||
|
||||
/* This could be the framebuffer */
|
||||
info->fb_pbase = i;
|
||||
|
||||
/* If it is prefetchable, it certainly is */
|
||||
if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (info->fb_pbase == n_pciaddrs) /* No candidates found */
|
||||
return (CN_DEAD);
|
||||
|
||||
#if defined(__powerpc__)
|
||||
OF_decode_addr(node, info->fb_pbase, &sc->sc_memt,
|
||||
&info->fb_vbase);
|
||||
#elif defined(__sparc64__)
|
||||
OF_decode_addr(node, info->fb_pbase, &space, &info->fb_pbase);
|
||||
sc->sc_memt = &vt_efb_memt[0];
|
||||
info->fb_vbase = sparc64_fake_bustag(space, info->fb_pbase,
|
||||
sc->sc_memt);
|
||||
#else
|
||||
bus_space_map(fdtbus_bs_tag, info->fb_pbase, info->fb_size,
|
||||
BUS_SPACE_MAP_PREFETCHABLE,
|
||||
(bus_space_handle_t *)&info->fb_vbase);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* blank full size */
|
||||
len = info->fb_size / 4;
|
||||
for (i = 0; i < len; i++) {
|
||||
((uint32_t *)info->fb_vbase)[i] = 0;
|
||||
}
|
||||
|
||||
/* Get pixel storage size. */
|
||||
info->fb_bpp = info->fb_stride / info->fb_width * 8;
|
||||
|
||||
/*
|
||||
* Early FB driver work with static window buffer 80x25, so reduce
|
||||
* size to 640x480.
|
||||
*/
|
||||
info->fb_width = VT_FB_DEFAULT_WIDTH;
|
||||
info->fb_height = VT_FB_DEFAULT_HEIGHT;
|
||||
|
||||
#ifdef FDT
|
||||
vt_efb_initialize(info, node);
|
||||
#else
|
||||
vt_efb_initialize(info);
|
||||
#endif
|
||||
fb_probe(info);
|
||||
vt_fb_init(vd);
|
||||
|
||||
|
||||
return (CN_INTERNAL);
|
||||
}
|
246
sys/dev/vt/hw/fb/vt_fb.c
Normal file
246
sys/dev/vt/hw/fb/vt_fb.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Aleksandr Rybalko under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/fbio.h>
|
||||
#include <dev/vt/vt.h>
|
||||
#include <dev/vt/hw/fb/vt_fb.h>
|
||||
#include <dev/vt/colors/vt_termcolors.h>
|
||||
|
||||
static struct vt_driver vt_fb_driver = {
|
||||
.vd_init = vt_fb_init,
|
||||
.vd_blank = vt_fb_blank,
|
||||
.vd_bitbltchr = vt_fb_bitbltchr,
|
||||
.vd_postswitch = vt_fb_postswitch,
|
||||
.vd_priority = VD_PRIORITY_GENERIC+10,
|
||||
};
|
||||
|
||||
void
|
||||
vt_fb_blank(struct vt_device *vd, term_color_t color)
|
||||
{
|
||||
struct fb_info *info;
|
||||
uint32_t c;
|
||||
u_int o;
|
||||
|
||||
info = vd->vd_softc;
|
||||
c = info->fb_cmap[color];
|
||||
|
||||
switch (FBTYPE_GET_BYTESPP(info)) {
|
||||
case 1:
|
||||
for (o = 0; o < info->fb_stride; o++)
|
||||
info->wr1(info, o, c);
|
||||
break;
|
||||
case 2:
|
||||
for (o = 0; o < info->fb_stride; o += 2)
|
||||
info->wr2(info, o, c);
|
||||
break;
|
||||
case 3:
|
||||
/* line 0 */
|
||||
for (o = 0; o < info->fb_stride; o += 3) {
|
||||
info->wr1(info, o, (c >> 16) & 0xff);
|
||||
info->wr1(info, o + 1, (c >> 8) & 0xff);
|
||||
info->wr1(info, o + 2, c & 0xff);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (o = 0; o < info->fb_stride; o += 4)
|
||||
info->wr4(info, o, c);
|
||||
break;
|
||||
default:
|
||||
/* panic? */
|
||||
return;
|
||||
}
|
||||
/* Copy line0 to all other lines. */
|
||||
/* XXX will copy with borders. */
|
||||
for (o = info->fb_stride; o < info->fb_size; o += info->fb_stride) {
|
||||
info->copy(info, o, 0, info->fb_stride);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vt_fb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
|
||||
int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
|
||||
unsigned int height, term_color_t fg, term_color_t bg)
|
||||
{
|
||||
struct fb_info *info;
|
||||
uint32_t fgc, bgc, cc, o;
|
||||
int c, l, bpp;
|
||||
u_long line;
|
||||
uint8_t b, m;
|
||||
const uint8_t *ch;
|
||||
|
||||
info = vd->vd_softc;
|
||||
bpp = FBTYPE_GET_BYTESPP(info);
|
||||
fgc = info->fb_cmap[fg];
|
||||
bgc = info->fb_cmap[bg];
|
||||
b = m = 0;
|
||||
if (bpl == 0)
|
||||
bpl = (width + 7) >> 3; /* Bytes per sorce line. */
|
||||
|
||||
/* Don't try to put off screen pixels */
|
||||
if (((left + width) > info->fb_width) || ((top + height) >
|
||||
info->fb_height))
|
||||
return;
|
||||
|
||||
line = (info->fb_stride * top) + (left * bpp);
|
||||
for (l = 0; l < height; l++) {
|
||||
ch = src;
|
||||
for (c = 0; c < width; c++) {
|
||||
if (c % 8 == 0)
|
||||
b = *ch++;
|
||||
else
|
||||
b <<= 1;
|
||||
if (mask != NULL) {
|
||||
if (c % 8 == 0)
|
||||
m = *mask++;
|
||||
else
|
||||
m <<= 1;
|
||||
/* Skip pixel write, if mask has no bit set. */
|
||||
if ((m & 0x80) == 0)
|
||||
continue;
|
||||
}
|
||||
o = line + (c * bpp);
|
||||
cc = b & 0x80 ? fgc : bgc;
|
||||
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
info->wr1(info, o, cc);
|
||||
break;
|
||||
case 2:
|
||||
info->wr2(info, o, cc);
|
||||
break;
|
||||
case 3:
|
||||
/* Packed mode, so unaligned. Byte access. */
|
||||
info->wr1(info, o, (cc >> 16) & 0xff);
|
||||
info->wr1(info, o + 1, (cc >> 8) & 0xff);
|
||||
info->wr1(info, o + 2, cc & 0xff);
|
||||
break;
|
||||
case 4:
|
||||
info->wr4(info, o, cc);
|
||||
break;
|
||||
default:
|
||||
/* panic? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
line += info->fb_stride;
|
||||
src += bpl;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vt_fb_postswitch(struct vt_device *vd)
|
||||
{
|
||||
struct fb_info *info;
|
||||
|
||||
info = vd->vd_softc;
|
||||
|
||||
if (info->enter != NULL)
|
||||
info->enter(info->fb_priv);
|
||||
}
|
||||
|
||||
static int
|
||||
vt_fb_init_cmap(uint32_t *cmap, int depth)
|
||||
{
|
||||
|
||||
switch (depth) {
|
||||
case 8:
|
||||
return (vt_generate_vga_palette(cmap, COLOR_FORMAT_RGB,
|
||||
0x7, 5, 0x7, 2, 0x3, 0));
|
||||
case 15:
|
||||
return (vt_generate_vga_palette(cmap, COLOR_FORMAT_RGB,
|
||||
0x1f, 10, 0x1f, 5, 0x1f, 0));
|
||||
case 16:
|
||||
return (vt_generate_vga_palette(cmap, COLOR_FORMAT_RGB,
|
||||
0x1f, 11, 0x3f, 5, 0x1f, 0));
|
||||
case 24:
|
||||
case 32: /* Ignore alpha. */
|
||||
return (vt_generate_vga_palette(cmap, COLOR_FORMAT_RGB,
|
||||
0xff, 0, 0xff, 8, 0xff, 16));
|
||||
default:
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
vt_fb_init(struct vt_device *vd)
|
||||
{
|
||||
struct fb_info *info;
|
||||
int err;
|
||||
|
||||
info = vd->vd_softc;
|
||||
vd->vd_height = info->fb_height;
|
||||
vd->vd_width = info->fb_width;
|
||||
|
||||
if (info->fb_cmsize <= 0) {
|
||||
err = vt_fb_init_cmap(info->fb_cmap, FBTYPE_GET_BPP(info));
|
||||
if (err)
|
||||
return (CN_DEAD);
|
||||
info->fb_cmsize = 16;
|
||||
}
|
||||
|
||||
/* Clear the screen. */
|
||||
vt_fb_blank(vd, TC_BLACK);
|
||||
|
||||
/* Wakeup screen. KMS need this. */
|
||||
vt_fb_postswitch(vd);
|
||||
|
||||
return (CN_INTERNAL);
|
||||
}
|
||||
|
||||
int
|
||||
vt_fb_attach(struct fb_info *info)
|
||||
{
|
||||
|
||||
vt_allocate(&vt_fb_driver, info);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
vt_fb_resume(void)
|
||||
{
|
||||
|
||||
vt_resume();
|
||||
}
|
||||
|
||||
void
|
||||
vt_fb_suspend(void)
|
||||
{
|
||||
|
||||
vt_suspend();
|
||||
}
|
47
sys/dev/vt/hw/fb/vt_fb.h
Normal file
47
sys/dev/vt/hw/fb/vt_fb.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*-
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Aleksandr Rybalko under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _DEV_VT_HW_FB_VT_FB_H_
|
||||
#define _DEV_VT_HW_FB_VT_FB_H_
|
||||
/* Generic framebuffer interface call vt_fb_attach to init VT(9) */
|
||||
int vt_fb_attach(struct fb_info *info);
|
||||
void vt_fb_resume(void);
|
||||
void vt_fb_suspend(void);
|
||||
|
||||
int fb_probe(struct fb_info *info);
|
||||
|
||||
vd_init_t vt_fb_init;
|
||||
vd_blank_t vt_fb_blank;
|
||||
vd_bitbltchr_t vt_fb_bitbltchr;
|
||||
vd_postswitch_t vt_fb_postswitch;
|
||||
|
||||
|
||||
#endif /* _DEV_VT_HW_FB_VT_FB_H_ */
|
348
sys/dev/vt/hw/ofwfb/ofwfb.c
Normal file
348
sys/dev/vt/hw/ofwfb/ofwfb.c
Normal file
@ -0,0 +1,348 @@
|
||||
/*-
|
||||
* Copyright (c) 2011 Nathan Whitehorn
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: user/ed/newcons/sys/dev/vt/hw/ofwfb/ofwfb.c 219888 2011-03-22 21:31:31Z ed $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
#include <dev/vt/colors/vt_termcolors.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#ifdef __sparc64__
|
||||
#include <machine/bus_private.h>
|
||||
#endif
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_pci.h>
|
||||
|
||||
struct ofwfb_softc {
|
||||
phandle_t sc_node;
|
||||
|
||||
intptr_t sc_addr;
|
||||
int sc_depth;
|
||||
int sc_stride;
|
||||
|
||||
bus_space_tag_t sc_memt;
|
||||
|
||||
uint32_t sc_colormap[16];
|
||||
};
|
||||
|
||||
static vd_init_t ofwfb_init;
|
||||
static vd_blank_t ofwfb_blank;
|
||||
static vd_bitbltchr_t ofwfb_bitbltchr;
|
||||
|
||||
static const struct vt_driver vt_ofwfb_driver = {
|
||||
.vd_init = ofwfb_init,
|
||||
.vd_blank = ofwfb_blank,
|
||||
.vd_bitbltchr = ofwfb_bitbltchr,
|
||||
.vd_priority = VD_PRIORITY_GENERIC+1,
|
||||
};
|
||||
|
||||
static struct ofwfb_softc ofwfb_conssoftc;
|
||||
VT_CONSDEV_DECLARE(vt_ofwfb_driver, PIXEL_WIDTH(1920), PIXEL_HEIGHT(1200),
|
||||
&ofwfb_conssoftc);
|
||||
/* XXX: hardcoded max size */
|
||||
|
||||
static void
|
||||
ofwfb_blank(struct vt_device *vd, term_color_t color)
|
||||
{
|
||||
struct ofwfb_softc *sc = vd->vd_softc;
|
||||
u_int ofs;
|
||||
uint32_t c;
|
||||
|
||||
switch (sc->sc_depth) {
|
||||
case 8:
|
||||
for (ofs = 0; ofs < sc->sc_stride*vd->vd_height; ofs++)
|
||||
*(uint8_t *)(sc->sc_addr + ofs) = color;
|
||||
break;
|
||||
case 32:
|
||||
c = sc->sc_colormap[color];
|
||||
for (ofs = 0; ofs < sc->sc_stride*vd->vd_height; ofs++)
|
||||
*(uint32_t *)(sc->sc_addr + 4*ofs) = c;
|
||||
break;
|
||||
default:
|
||||
/* panic? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ofwfb_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
|
||||
int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
|
||||
unsigned int height, term_color_t fg, term_color_t bg)
|
||||
{
|
||||
struct ofwfb_softc *sc = vd->vd_softc;
|
||||
u_long line;
|
||||
uint32_t fgc, bgc;
|
||||
int c;
|
||||
uint8_t b, m;
|
||||
|
||||
fgc = sc->sc_colormap[fg];
|
||||
bgc = sc->sc_colormap[bg];
|
||||
b = m = 0;
|
||||
|
||||
/* Don't try to put off screen pixels */
|
||||
if (((left + width) > vd->vd_width) || ((top + height) >
|
||||
vd->vd_height))
|
||||
return;
|
||||
|
||||
line = (sc->sc_stride * top) + left * sc->sc_depth/8;
|
||||
for (; height > 0; height--) {
|
||||
for (c = 0; c < width; c++) {
|
||||
if (c % 8 == 0)
|
||||
b = *src++;
|
||||
else
|
||||
b <<= 1;
|
||||
if (mask != NULL) {
|
||||
if (c % 8 == 0)
|
||||
m = *mask++;
|
||||
else
|
||||
m <<= 1;
|
||||
/* Skip pixel write, if mask has no bit set. */
|
||||
if ((m & 0x80) == 0)
|
||||
continue;
|
||||
}
|
||||
switch(sc->sc_depth) {
|
||||
case 8:
|
||||
*(uint8_t *)(sc->sc_addr + line + c) =
|
||||
b & 0x80 ? fg : bg;
|
||||
break;
|
||||
case 32:
|
||||
*(uint32_t *)(sc->sc_addr + line + 4*c) =
|
||||
(b & 0x80) ? fgc : bgc;
|
||||
break;
|
||||
default:
|
||||
/* panic? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
line += sc->sc_stride;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ofwfb_initialize(struct vt_device *vd)
|
||||
{
|
||||
struct ofwfb_softc *sc = vd->vd_softc;
|
||||
char name[64];
|
||||
ihandle_t ih;
|
||||
int i;
|
||||
cell_t retval;
|
||||
uint32_t oldpix;
|
||||
|
||||
/* Open display device, thereby initializing it */
|
||||
memset(name, 0, sizeof(name));
|
||||
OF_package_to_path(sc->sc_node, name, sizeof(name));
|
||||
ih = OF_open(name);
|
||||
|
||||
/*
|
||||
* Set up the color map
|
||||
*/
|
||||
|
||||
switch (sc->sc_depth) {
|
||||
case 8:
|
||||
vt_generate_vga_palette(sc->sc_colormap, COLOR_FORMAT_RGB, 255,
|
||||
0, 255, 8, 255, 16);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
OF_call_method("color!", ih, 4, 1,
|
||||
(cell_t)((sc->sc_colormap[i] >> 16) & 0xff),
|
||||
(cell_t)((sc->sc_colormap[i] >> 8) & 0xff),
|
||||
(cell_t)((sc->sc_colormap[i] >> 0) & 0xff),
|
||||
(cell_t)i, &retval);
|
||||
}
|
||||
break;
|
||||
|
||||
case 32:
|
||||
/*
|
||||
* We bypass the usual bus_space_() accessors here, mostly
|
||||
* for performance reasons. In particular, we don't want
|
||||
* any barrier operations that may be performed and handle
|
||||
* endianness slightly different. Figure out the host-view
|
||||
* endianness of the frame buffer.
|
||||
*/
|
||||
oldpix = bus_space_read_4(sc->sc_memt, sc->sc_addr, 0);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_addr, 0, 0xff000000);
|
||||
if (*(uint8_t *)(sc->sc_addr) == 0xff)
|
||||
vt_generate_vga_palette(sc->sc_colormap,
|
||||
COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0);
|
||||
else
|
||||
vt_generate_vga_palette(sc->sc_colormap,
|
||||
COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_addr, 0, oldpix);
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Unknown color space depth %d", sc->sc_depth);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Clear the screen. */
|
||||
ofwfb_blank(vd, TC_BLACK);
|
||||
}
|
||||
|
||||
static int
|
||||
ofwfb_init(struct vt_device *vd)
|
||||
{
|
||||
struct ofwfb_softc *sc = vd->vd_softc;
|
||||
char type[64];
|
||||
phandle_t chosen;
|
||||
ihandle_t stdout;
|
||||
phandle_t node;
|
||||
uint32_t depth, height, width;
|
||||
struct ofw_pci_register pciaddrs[8];
|
||||
int n_pciaddrs;
|
||||
uint32_t fb_phys;
|
||||
int i, len;
|
||||
#ifdef __sparc64__
|
||||
static struct bus_space_tag ofwfb_memt[1];
|
||||
bus_addr_t phys;
|
||||
int space;
|
||||
#endif
|
||||
|
||||
chosen = OF_finddevice("/chosen");
|
||||
OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
|
||||
node = OF_instance_to_package(stdout);
|
||||
if (node == -1) {
|
||||
/*
|
||||
* The "/chosen/stdout" does not exist try
|
||||
* using "screen" directly.
|
||||
*/
|
||||
node = OF_finddevice("screen");
|
||||
}
|
||||
OF_getprop(node, "device_type", type, sizeof(type));
|
||||
if (strcmp(type, "display") != 0)
|
||||
return (CN_DEAD);
|
||||
|
||||
/* Keep track of the OF node */
|
||||
sc->sc_node = node;
|
||||
|
||||
/* Make sure we have needed properties */
|
||||
if (OF_getproplen(node, "height") != sizeof(height) ||
|
||||
OF_getproplen(node, "width") != sizeof(width) ||
|
||||
OF_getproplen(node, "depth") != sizeof(depth) ||
|
||||
OF_getproplen(node, "linebytes") != sizeof(sc->sc_stride))
|
||||
return (CN_DEAD);
|
||||
|
||||
/* Only support 8 and 32-bit framebuffers */
|
||||
OF_getprop(node, "depth", &depth, sizeof(depth));
|
||||
if (depth != 8 && depth != 32)
|
||||
return (CN_DEAD);
|
||||
sc->sc_depth = depth;
|
||||
|
||||
OF_getprop(node, "height", &height, sizeof(height));
|
||||
OF_getprop(node, "width", &width, sizeof(width));
|
||||
OF_getprop(node, "linebytes", &sc->sc_stride, sizeof(sc->sc_stride));
|
||||
|
||||
vd->vd_height = height;
|
||||
vd->vd_width = width;
|
||||
|
||||
/*
|
||||
* Get the PCI addresses of the adapter, if present. The node may be the
|
||||
* child of the PCI device: in that case, try the parent for
|
||||
* the assigned-addresses property.
|
||||
*/
|
||||
len = OF_getprop(node, "assigned-addresses", pciaddrs,
|
||||
sizeof(pciaddrs));
|
||||
if (len == -1) {
|
||||
len = OF_getprop(OF_parent(node), "assigned-addresses",
|
||||
pciaddrs, sizeof(pciaddrs));
|
||||
}
|
||||
if (len == -1)
|
||||
len = 0;
|
||||
n_pciaddrs = len / sizeof(struct ofw_pci_register);
|
||||
|
||||
/*
|
||||
* Grab the physical address of the framebuffer, and then map it
|
||||
* into our memory space. If the MMU is not yet up, it will be
|
||||
* remapped for us when relocation turns on.
|
||||
*/
|
||||
if (OF_getproplen(node, "address") == sizeof(fb_phys)) {
|
||||
/* XXX We assume #address-cells is 1 at this point. */
|
||||
OF_getprop(node, "address", &fb_phys, sizeof(fb_phys));
|
||||
|
||||
#if defined(__powerpc__)
|
||||
sc->sc_memt = &bs_be_tag;
|
||||
bus_space_map(sc->sc_memt, fb_phys, height * sc->sc_stride,
|
||||
BUS_SPACE_MAP_PREFETCHABLE, &sc->sc_addr);
|
||||
#elif defined(__sparc64__)
|
||||
OF_decode_addr(node, 0, &space, &phys);
|
||||
sc->sc_memt = &ofwfb_memt[0];
|
||||
sc->sc_addr = sparc64_fake_bustag(space, fb_phys, sc->sc_memt);
|
||||
#else
|
||||
#error Unsupported platform!
|
||||
#endif
|
||||
} else {
|
||||
/*
|
||||
* Some IBM systems don't have an address property. Try to
|
||||
* guess the framebuffer region from the assigned addresses.
|
||||
* This is ugly, but there doesn't seem to be an alternative.
|
||||
* Linux does the same thing.
|
||||
*/
|
||||
|
||||
fb_phys = n_pciaddrs;
|
||||
for (i = 0; i < n_pciaddrs; i++) {
|
||||
/* If it is too small, not the framebuffer */
|
||||
if (pciaddrs[i].size_lo < sc->sc_stride*height)
|
||||
continue;
|
||||
/* If it is not memory, it isn't either */
|
||||
if (!(pciaddrs[i].phys_hi &
|
||||
OFW_PCI_PHYS_HI_SPACE_MEM32))
|
||||
continue;
|
||||
|
||||
/* This could be the framebuffer */
|
||||
fb_phys = i;
|
||||
|
||||
/* If it is prefetchable, it certainly is */
|
||||
if (pciaddrs[i].phys_hi & OFW_PCI_PHYS_HI_PREFETCHABLE)
|
||||
break;
|
||||
}
|
||||
|
||||
if (fb_phys == n_pciaddrs) /* No candidates found */
|
||||
return (CN_DEAD);
|
||||
|
||||
#if defined(__powerpc__)
|
||||
OF_decode_addr(node, fb_phys, &sc->sc_memt, &sc->sc_addr);
|
||||
#elif defined(__sparc64__)
|
||||
OF_decode_addr(node, fb_phys, &space, &phys);
|
||||
sc->sc_memt = &ofwfb_memt[0];
|
||||
sc->sc_addr = sparc64_fake_bustag(space, phys, sc->sc_memt);
|
||||
#endif
|
||||
}
|
||||
|
||||
ofwfb_initialize(vd);
|
||||
|
||||
return (CN_INTERNAL);
|
||||
}
|
||||
|
604
sys/dev/vt/hw/vga/vga.c
Normal file
604
sys/dev/vt/hw/vga/vga.c
Normal file
@ -0,0 +1,604 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Ed Schouten
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
#include <dev/vt/hw/vga/vga_reg.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/vmparam.h>
|
||||
#endif /* __amd64__ || __i386__ */
|
||||
|
||||
struct vga_softc {
|
||||
bus_space_tag_t vga_fb_tag;
|
||||
bus_space_handle_t vga_fb_handle;
|
||||
bus_space_tag_t vga_reg_tag;
|
||||
bus_space_handle_t vga_reg_handle;
|
||||
int vga_curcolor;
|
||||
};
|
||||
|
||||
/* Convenience macros. */
|
||||
#define MEM_READ1(sc, ofs) \
|
||||
bus_space_read_1(sc->vga_fb_tag, sc->vga_fb_handle, ofs)
|
||||
#define MEM_WRITE1(sc, ofs, val) \
|
||||
bus_space_write_1(sc->vga_fb_tag, sc->vga_fb_handle, ofs, val)
|
||||
#define REG_READ1(sc, reg) \
|
||||
bus_space_read_1(sc->vga_reg_tag, sc->vga_reg_handle, reg)
|
||||
#define REG_WRITE1(sc, reg, val) \
|
||||
bus_space_write_1(sc->vga_reg_tag, sc->vga_reg_handle, reg, val)
|
||||
|
||||
#define VT_VGA_WIDTH 640
|
||||
#define VT_VGA_HEIGHT 480
|
||||
#define VT_VGA_MEMSIZE (VT_VGA_WIDTH * VT_VGA_HEIGHT / 8)
|
||||
|
||||
static vd_init_t vga_init;
|
||||
static vd_blank_t vga_blank;
|
||||
static vd_bitbltchr_t vga_bitbltchr;
|
||||
static vd_putchar_t vga_putchar;
|
||||
|
||||
static const struct vt_driver vt_vga_driver = {
|
||||
.vd_init = vga_init,
|
||||
.vd_blank = vga_blank,
|
||||
.vd_bitbltchr = vga_bitbltchr,
|
||||
.vd_putchar = vga_putchar,
|
||||
.vd_priority = VD_PRIORITY_GENERIC,
|
||||
};
|
||||
|
||||
/*
|
||||
* Driver supports both text mode and graphics mode. Make sure the
|
||||
* buffer is always big enough to support both.
|
||||
*/
|
||||
static struct vga_softc vga_conssoftc;
|
||||
VT_CONSDEV_DECLARE(vt_vga_driver, MAX(80, PIXEL_WIDTH(VT_VGA_WIDTH)),
|
||||
MAX(25, PIXEL_HEIGHT(VT_VGA_HEIGHT)), &vga_conssoftc);
|
||||
|
||||
static inline void
|
||||
vga_setcolor(struct vt_device *vd, term_color_t color)
|
||||
{
|
||||
struct vga_softc *sc = vd->vd_softc;
|
||||
|
||||
if (sc->vga_curcolor != color) {
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, color);
|
||||
sc->vga_curcolor = color;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vga_blank(struct vt_device *vd, term_color_t color)
|
||||
{
|
||||
struct vga_softc *sc = vd->vd_softc;
|
||||
u_int ofs;
|
||||
|
||||
vga_setcolor(vd, color);
|
||||
for (ofs = 0; ofs < VT_VGA_MEMSIZE; ofs++)
|
||||
MEM_WRITE1(sc, ofs, 0xff);
|
||||
}
|
||||
|
||||
static inline void
|
||||
vga_bitblt_put(struct vt_device *vd, u_long dst, term_color_t color,
|
||||
uint8_t v)
|
||||
{
|
||||
struct vga_softc *sc = vd->vd_softc;
|
||||
|
||||
/* Skip empty writes, in order to avoid palette changes. */
|
||||
if (v != 0x00) {
|
||||
vga_setcolor(vd, color);
|
||||
/*
|
||||
* When this MEM_READ1() gets disabled, all sorts of
|
||||
* artifacts occur. This is because this read loads the
|
||||
* set of 8 pixels that are about to be changed. There
|
||||
* is one scenario where we can avoid the read, namely
|
||||
* if all pixels are about to be overwritten anyway.
|
||||
*/
|
||||
if (v != 0xff)
|
||||
MEM_READ1(sc, dst);
|
||||
MEM_WRITE1(sc, dst, v);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
vga_bitblt_draw(struct vt_device *vd, const uint8_t *src,
|
||||
u_long ldst, uint8_t shift, unsigned int width, unsigned int height,
|
||||
term_color_t color, int negate)
|
||||
{
|
||||
u_long dst;
|
||||
int w;
|
||||
uint8_t b, r, out;
|
||||
|
||||
for (; height > 0; height--) {
|
||||
dst = ldst;
|
||||
ldst += VT_VGA_WIDTH / 8;
|
||||
r = 0;
|
||||
for (w = width; w > 0; w -= 8) {
|
||||
b = *src++;
|
||||
if (negate) {
|
||||
b = ~b;
|
||||
/* Don't go too far. */
|
||||
if (w < 8)
|
||||
b &= 0xff << (8 - w);
|
||||
}
|
||||
/* Reintroduce bits from previous column. */
|
||||
out = (b >> shift) | r;
|
||||
r = b << (8 - shift);
|
||||
vga_bitblt_put(vd, dst++, color, out);
|
||||
}
|
||||
/* Print the remainder. */
|
||||
vga_bitblt_put(vd, dst, color, r);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vga_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
|
||||
int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
|
||||
unsigned int height, term_color_t fg, term_color_t bg)
|
||||
{
|
||||
struct vga_softc *sc = vd->vd_softc;
|
||||
u_long dst;
|
||||
uint8_t shift;
|
||||
|
||||
dst = (VT_VGA_WIDTH * top + left) / 8;
|
||||
shift = left % 8;
|
||||
|
||||
/* Don't try to put off screen pixels */
|
||||
if (((left + width) > VT_VGA_WIDTH) || ((top + height) >
|
||||
VT_VGA_HEIGHT))
|
||||
return;
|
||||
|
||||
if (sc->vga_curcolor == fg) {
|
||||
vga_bitblt_draw(vd, src, dst, shift, width, height, fg, 0);
|
||||
vga_bitblt_draw(vd, src, dst, shift, width, height, bg, 1);
|
||||
} else {
|
||||
vga_bitblt_draw(vd, src, dst, shift, width, height, bg, 1);
|
||||
vga_bitblt_draw(vd, src, dst, shift, width, height, fg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Binary searchable table for Unicode to CP437 conversion.
|
||||
*/
|
||||
|
||||
struct unicp437 {
|
||||
uint16_t unicode_base;
|
||||
uint8_t cp437_base;
|
||||
uint8_t length;
|
||||
};
|
||||
|
||||
static const struct unicp437 cp437table[] = {
|
||||
{ 0x0020, 0x20, 0x5e }, { 0x00a0, 0x20, 0x00 },
|
||||
{ 0x00a1, 0xad, 0x00 }, { 0x00a2, 0x9b, 0x00 },
|
||||
{ 0x00a3, 0x9c, 0x00 }, { 0x00a5, 0x9d, 0x00 },
|
||||
{ 0x00a7, 0x15, 0x00 }, { 0x00aa, 0xa6, 0x00 },
|
||||
{ 0x00ab, 0xae, 0x00 }, { 0x00ac, 0xaa, 0x00 },
|
||||
{ 0x00b0, 0xf8, 0x00 }, { 0x00b1, 0xf1, 0x00 },
|
||||
{ 0x00b2, 0xfd, 0x00 }, { 0x00b5, 0xe6, 0x00 },
|
||||
{ 0x00b6, 0x14, 0x00 }, { 0x00b7, 0xfa, 0x00 },
|
||||
{ 0x00ba, 0xa7, 0x00 }, { 0x00bb, 0xaf, 0x00 },
|
||||
{ 0x00bc, 0xac, 0x00 }, { 0x00bd, 0xab, 0x00 },
|
||||
{ 0x00bf, 0xa8, 0x00 }, { 0x00c4, 0x8e, 0x01 },
|
||||
{ 0x00c6, 0x92, 0x00 }, { 0x00c7, 0x80, 0x00 },
|
||||
{ 0x00c9, 0x90, 0x00 }, { 0x00d1, 0xa5, 0x00 },
|
||||
{ 0x00d6, 0x99, 0x00 }, { 0x00dc, 0x9a, 0x00 },
|
||||
{ 0x00df, 0xe1, 0x00 }, { 0x00e0, 0x85, 0x00 },
|
||||
{ 0x00e1, 0xa0, 0x00 }, { 0x00e2, 0x83, 0x00 },
|
||||
{ 0x00e4, 0x84, 0x00 }, { 0x00e5, 0x86, 0x00 },
|
||||
{ 0x00e6, 0x91, 0x00 }, { 0x00e7, 0x87, 0x00 },
|
||||
{ 0x00e8, 0x8a, 0x00 }, { 0x00e9, 0x82, 0x00 },
|
||||
{ 0x00ea, 0x88, 0x01 }, { 0x00ec, 0x8d, 0x00 },
|
||||
{ 0x00ed, 0xa1, 0x00 }, { 0x00ee, 0x8c, 0x00 },
|
||||
{ 0x00ef, 0x8b, 0x00 }, { 0x00f0, 0xeb, 0x00 },
|
||||
{ 0x00f1, 0xa4, 0x00 }, { 0x00f2, 0x95, 0x00 },
|
||||
{ 0x00f3, 0xa2, 0x00 }, { 0x00f4, 0x93, 0x00 },
|
||||
{ 0x00f6, 0x94, 0x00 }, { 0x00f7, 0xf6, 0x00 },
|
||||
{ 0x00f8, 0xed, 0x00 }, { 0x00f9, 0x97, 0x00 },
|
||||
{ 0x00fa, 0xa3, 0x00 }, { 0x00fb, 0x96, 0x00 },
|
||||
{ 0x00fc, 0x81, 0x00 }, { 0x00ff, 0x98, 0x00 },
|
||||
{ 0x0192, 0x9f, 0x00 }, { 0x0393, 0xe2, 0x00 },
|
||||
{ 0x0398, 0xe9, 0x00 }, { 0x03a3, 0xe4, 0x00 },
|
||||
{ 0x03a6, 0xe8, 0x00 }, { 0x03a9, 0xea, 0x00 },
|
||||
{ 0x03b1, 0xe0, 0x01 }, { 0x03b4, 0xeb, 0x00 },
|
||||
{ 0x03b5, 0xee, 0x00 }, { 0x03bc, 0xe6, 0x00 },
|
||||
{ 0x03c0, 0xe3, 0x00 }, { 0x03c3, 0xe5, 0x00 },
|
||||
{ 0x03c4, 0xe7, 0x00 }, { 0x03c6, 0xed, 0x00 },
|
||||
{ 0x03d5, 0xed, 0x00 }, { 0x2010, 0x2d, 0x00 },
|
||||
{ 0x2014, 0x2d, 0x00 }, { 0x2018, 0x60, 0x00 },
|
||||
{ 0x2019, 0x27, 0x00 }, { 0x201c, 0x22, 0x00 },
|
||||
{ 0x201d, 0x22, 0x00 }, { 0x2022, 0x07, 0x00 },
|
||||
{ 0x203c, 0x13, 0x00 }, { 0x207f, 0xfc, 0x00 },
|
||||
{ 0x20a7, 0x9e, 0x00 }, { 0x20ac, 0xee, 0x00 },
|
||||
{ 0x2126, 0xea, 0x00 }, { 0x2190, 0x1b, 0x00 },
|
||||
{ 0x2191, 0x18, 0x00 }, { 0x2192, 0x1a, 0x00 },
|
||||
{ 0x2193, 0x19, 0x00 }, { 0x2194, 0x1d, 0x00 },
|
||||
{ 0x2195, 0x12, 0x00 }, { 0x21a8, 0x17, 0x00 },
|
||||
{ 0x2202, 0xeb, 0x00 }, { 0x2208, 0xee, 0x00 },
|
||||
{ 0x2211, 0xe4, 0x00 }, { 0x2212, 0x2d, 0x00 },
|
||||
{ 0x2219, 0xf9, 0x00 }, { 0x221a, 0xfb, 0x00 },
|
||||
{ 0x221e, 0xec, 0x00 }, { 0x221f, 0x1c, 0x00 },
|
||||
{ 0x2229, 0xef, 0x00 }, { 0x2248, 0xf7, 0x00 },
|
||||
{ 0x2261, 0xf0, 0x00 }, { 0x2264, 0xf3, 0x00 },
|
||||
{ 0x2265, 0xf2, 0x00 }, { 0x2302, 0x7f, 0x00 },
|
||||
{ 0x2310, 0xa9, 0x00 }, { 0x2320, 0xf4, 0x00 },
|
||||
{ 0x2321, 0xf5, 0x00 }, { 0x2500, 0xc4, 0x00 },
|
||||
{ 0x2502, 0xb3, 0x00 }, { 0x250c, 0xda, 0x00 },
|
||||
{ 0x2510, 0xbf, 0x00 }, { 0x2514, 0xc0, 0x00 },
|
||||
{ 0x2518, 0xd9, 0x00 }, { 0x251c, 0xc3, 0x00 },
|
||||
{ 0x2524, 0xb4, 0x00 }, { 0x252c, 0xc2, 0x00 },
|
||||
{ 0x2534, 0xc1, 0x00 }, { 0x253c, 0xc5, 0x00 },
|
||||
{ 0x2550, 0xcd, 0x00 }, { 0x2551, 0xba, 0x00 },
|
||||
{ 0x2552, 0xd5, 0x00 }, { 0x2553, 0xd6, 0x00 },
|
||||
{ 0x2554, 0xc9, 0x00 }, { 0x2555, 0xb8, 0x00 },
|
||||
{ 0x2556, 0xb7, 0x00 }, { 0x2557, 0xbb, 0x00 },
|
||||
{ 0x2558, 0xd4, 0x00 }, { 0x2559, 0xd3, 0x00 },
|
||||
{ 0x255a, 0xc8, 0x00 }, { 0x255b, 0xbe, 0x00 },
|
||||
{ 0x255c, 0xbd, 0x00 }, { 0x255d, 0xbc, 0x00 },
|
||||
{ 0x255e, 0xc6, 0x01 }, { 0x2560, 0xcc, 0x00 },
|
||||
{ 0x2561, 0xb5, 0x00 }, { 0x2562, 0xb6, 0x00 },
|
||||
{ 0x2563, 0xb9, 0x00 }, { 0x2564, 0xd1, 0x01 },
|
||||
{ 0x2566, 0xcb, 0x00 }, { 0x2567, 0xcf, 0x00 },
|
||||
{ 0x2568, 0xd0, 0x00 }, { 0x2569, 0xca, 0x00 },
|
||||
{ 0x256a, 0xd8, 0x00 }, { 0x256b, 0xd7, 0x00 },
|
||||
{ 0x256c, 0xce, 0x00 }, { 0x2580, 0xdf, 0x00 },
|
||||
{ 0x2584, 0xdc, 0x00 }, { 0x2588, 0xdb, 0x00 },
|
||||
{ 0x258c, 0xdd, 0x00 }, { 0x2590, 0xde, 0x00 },
|
||||
{ 0x2591, 0xb0, 0x02 }, { 0x25a0, 0xfe, 0x00 },
|
||||
{ 0x25ac, 0x16, 0x00 }, { 0x25b2, 0x1e, 0x00 },
|
||||
{ 0x25ba, 0x10, 0x00 }, { 0x25bc, 0x1f, 0x00 },
|
||||
{ 0x25c4, 0x11, 0x00 }, { 0x25cb, 0x09, 0x00 },
|
||||
{ 0x25d8, 0x08, 0x00 }, { 0x25d9, 0x0a, 0x00 },
|
||||
{ 0x263a, 0x01, 0x01 }, { 0x263c, 0x0f, 0x00 },
|
||||
{ 0x2640, 0x0c, 0x00 }, { 0x2642, 0x0b, 0x00 },
|
||||
{ 0x2660, 0x06, 0x00 }, { 0x2663, 0x05, 0x00 },
|
||||
{ 0x2665, 0x03, 0x01 }, { 0x266a, 0x0d, 0x01 },
|
||||
};
|
||||
|
||||
static uint8_t
|
||||
vga_get_cp437(term_char_t c)
|
||||
{
|
||||
int min, mid, max;
|
||||
|
||||
min = 0;
|
||||
max = (sizeof(cp437table) / sizeof(struct unicp437)) - 1;
|
||||
|
||||
if (c < cp437table[0].unicode_base ||
|
||||
c > cp437table[max].unicode_base + cp437table[max].length)
|
||||
return '?';
|
||||
|
||||
while (max >= min) {
|
||||
mid = (min + max) / 2;
|
||||
if (c < cp437table[mid].unicode_base)
|
||||
max = mid - 1;
|
||||
else if (c > cp437table[mid].unicode_base +
|
||||
cp437table[mid].length)
|
||||
min = mid + 1;
|
||||
else
|
||||
return (c - cp437table[mid].unicode_base +
|
||||
cp437table[mid].cp437_base);
|
||||
}
|
||||
|
||||
return '?';
|
||||
}
|
||||
|
||||
static void
|
||||
vga_putchar(struct vt_device *vd, term_char_t c,
|
||||
vt_axis_t top, vt_axis_t left, term_color_t fg, term_color_t bg)
|
||||
{
|
||||
struct vga_softc *sc = vd->vd_softc;
|
||||
uint8_t ch, attr;
|
||||
|
||||
/*
|
||||
* Convert character to CP437, which is the character set used
|
||||
* by the VGA hardware by default.
|
||||
*/
|
||||
ch = vga_get_cp437(c);
|
||||
|
||||
/*
|
||||
* Convert colors to VGA attributes.
|
||||
*/
|
||||
attr = bg << 4 | fg;
|
||||
|
||||
MEM_WRITE1(sc, 0x18000 + (top * 80 + left) * 2 + 0, ch);
|
||||
MEM_WRITE1(sc, 0x18000 + (top * 80 + left) * 2 + 1, attr);
|
||||
}
|
||||
|
||||
static void
|
||||
vga_initialize_graphics(struct vt_device *vd)
|
||||
{
|
||||
struct vga_softc *sc = vd->vd_softc;
|
||||
|
||||
/* Clock select. */
|
||||
REG_WRITE1(sc, VGA_GEN_MISC_OUTPUT_W, VGA_GEN_MO_VSP | VGA_GEN_MO_HSP |
|
||||
VGA_GEN_MO_PB | VGA_GEN_MO_ER | VGA_GEN_MO_IOA);
|
||||
/* Set sequencer clocking and memory mode. */
|
||||
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_CLOCKING_MODE);
|
||||
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_CM_89);
|
||||
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_MEMORY_MODE);
|
||||
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_MM_OE | VGA_SEQ_MM_EM);
|
||||
|
||||
/* Set the graphics controller in graphics mode. */
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_MISCELLANEOUS);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0x04 + VGA_GC_MISC_GA);
|
||||
/* Program the CRT controller. */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_HORIZ_TOTAL);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x5f); /* 760 */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_HORIZ_DISP_END);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x4f); /* 640 - 8 */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_HORIZ_BLANK);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x50); /* 640 */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_END_HORIZ_BLANK);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_EHB_CR + 2);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_HORIZ_RETRACE);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x54); /* 672 */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_END_HORIZ_RETRACE);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_EHR_EHB + 0);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_TOTAL);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x0b); /* 523 */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_OVERFLOW);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_OF_VT9 | VGA_CRTC_OF_LC8 |
|
||||
VGA_CRTC_OF_VBS8 | VGA_CRTC_OF_VRS8 | VGA_CRTC_OF_VDE8);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MAX_SCAN_LINE);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_MSL_LC9);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_RETRACE_START);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0xea); /* 480 + 10 */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_RETRACE_END);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x0c);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_DISPLAY_END);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0xdf); /* 480 - 1*/
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_OFFSET);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x28);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_VERT_BLANK);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0xe7); /* 480 + 7 */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_END_VERT_BLANK);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x04);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MODE_CONTROL);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_MC_WB | VGA_CRTC_MC_AW |
|
||||
VGA_CRTC_MC_SRS | VGA_CRTC_MC_CMS);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_LINE_COMPARE);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0xff); /* 480 + 31 */
|
||||
|
||||
REG_WRITE1(sc, VGA_GEN_FEATURE_CTRL_W, 0);
|
||||
|
||||
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_MAP_MASK);
|
||||
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_MM_EM3 | VGA_SEQ_MM_EM2 |
|
||||
VGA_SEQ_MM_EM1 | VGA_SEQ_MM_EM0);
|
||||
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_CHAR_MAP_SELECT);
|
||||
REG_WRITE1(sc, VGA_SEQ_DATA, 0);
|
||||
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_ENABLE_SET_RESET);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0x0f);
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_COLOR_COMPARE);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_DATA_ROTATE);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_READ_MAP_SELECT);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_MODE);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_COLOR_DONT_CARE);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0x0f);
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_BIT_MASK);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0xff);
|
||||
}
|
||||
|
||||
static void
|
||||
vga_initialize(struct vt_device *vd, int textmode)
|
||||
{
|
||||
struct vga_softc *sc = vd->vd_softc;
|
||||
uint8_t x;
|
||||
|
||||
/* Make sure the VGA adapter is not in monochrome emulation mode. */
|
||||
x = REG_READ1(sc, VGA_GEN_MISC_OUTPUT_R);
|
||||
REG_WRITE1(sc, VGA_GEN_MISC_OUTPUT_W, x | VGA_GEN_MO_IOA);
|
||||
|
||||
/* Unprotect CRTC registers 0-7. */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_VERT_RETRACE_END);
|
||||
x = REG_READ1(sc, VGA_CRTC_DATA);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, x & ~VGA_CRTC_VRE_PR);
|
||||
|
||||
/*
|
||||
* Wait for the vertical retrace.
|
||||
* NOTE: this code reads the VGA_GEN_INPUT_STAT_1 register, which has
|
||||
* the side-effect of clearing the internal flip-flip of the attribute
|
||||
* controller's write register. This means that because this code is
|
||||
* here, we know for sure that the first write to the attribute
|
||||
* controller will be a write to the address register. Removing this
|
||||
* code therefore also removes that guarantee and appropriate measures
|
||||
* need to be taken.
|
||||
*/
|
||||
do {
|
||||
x = REG_READ1(sc, VGA_GEN_INPUT_STAT_1);
|
||||
x &= VGA_GEN_IS1_VR | VGA_GEN_IS1_DE;
|
||||
} while (x != (VGA_GEN_IS1_VR | VGA_GEN_IS1_DE));
|
||||
|
||||
/* Now, disable the sync. signals. */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MODE_CONTROL);
|
||||
x = REG_READ1(sc, VGA_CRTC_DATA);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, x & ~VGA_CRTC_MC_HR);
|
||||
|
||||
/* Asynchronous sequencer reset. */
|
||||
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_RESET);
|
||||
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_RST_SR);
|
||||
|
||||
if (!textmode)
|
||||
vga_initialize_graphics(vd);
|
||||
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_PRESET_ROW_SCAN);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_CURSOR_START);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_CS_COO);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_CURSOR_END);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_ADDR_HIGH);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_START_ADDR_LOW);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_CURSOR_LOC_HIGH);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_CURSOR_LOC_LOW);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, 0x59);
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_UNDERLINE_LOC);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, VGA_CRTC_UL_UL);
|
||||
|
||||
if (textmode) {
|
||||
/* Set the attribute controller to blink disable. */
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_MODE_CONTROL);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, 0);
|
||||
} else {
|
||||
/* Set the attribute controller in graphics mode. */
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_MODE_CONTROL);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_MC_GA);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_HORIZ_PIXEL_PANNING);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, 0);
|
||||
}
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(0));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, 0);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(1));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(2));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_G);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(3));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SG | VGA_AC_PAL_R);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(4));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_B);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(5));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R | VGA_AC_PAL_B);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(6));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_G | VGA_AC_PAL_B);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(7));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R | VGA_AC_PAL_G | VGA_AC_PAL_B);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(8));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
|
||||
VGA_AC_PAL_SB);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(9));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
|
||||
VGA_AC_PAL_SB | VGA_AC_PAL_R);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(10));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
|
||||
VGA_AC_PAL_SB | VGA_AC_PAL_G);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(11));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
|
||||
VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_G);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(12));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
|
||||
VGA_AC_PAL_SB | VGA_AC_PAL_B);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(13));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
|
||||
VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_B);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(14));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
|
||||
VGA_AC_PAL_SB | VGA_AC_PAL_G | VGA_AC_PAL_B);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(15));
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG |
|
||||
VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_G | VGA_AC_PAL_B);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_OVERSCAN_COLOR);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, 0);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_COLOR_PLANE_ENABLE);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, 0x0f);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_COLOR_SELECT);
|
||||
REG_WRITE1(sc, VGA_AC_WRITE, 0);
|
||||
|
||||
if (!textmode) {
|
||||
u_int ofs;
|
||||
|
||||
/*
|
||||
* Done. Clear the frame buffer. All bit planes are
|
||||
* enabled, so a single-paged loop should clear all
|
||||
* planes.
|
||||
*/
|
||||
for (ofs = 0; ofs < VT_VGA_MEMSIZE; ofs++) {
|
||||
MEM_READ1(sc, ofs);
|
||||
MEM_WRITE1(sc, ofs, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-enable the sequencer. */
|
||||
REG_WRITE1(sc, VGA_SEQ_ADDRESS, VGA_SEQ_RESET);
|
||||
REG_WRITE1(sc, VGA_SEQ_DATA, VGA_SEQ_RST_SR | VGA_SEQ_RST_NAR);
|
||||
/* Re-enable the sync signals. */
|
||||
REG_WRITE1(sc, VGA_CRTC_ADDRESS, VGA_CRTC_MODE_CONTROL);
|
||||
x = REG_READ1(sc, VGA_CRTC_DATA);
|
||||
REG_WRITE1(sc, VGA_CRTC_DATA, x | VGA_CRTC_MC_HR);
|
||||
|
||||
if (!textmode) {
|
||||
/* Switch to write mode 3, because we'll mainly do bitblt. */
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_MODE);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 3);
|
||||
REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_ENABLE_SET_RESET);
|
||||
REG_WRITE1(sc, VGA_GC_DATA, 0x0f);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vga_init(struct vt_device *vd)
|
||||
{
|
||||
struct vga_softc *sc = vd->vd_softc;
|
||||
int textmode = 0;
|
||||
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
sc->vga_fb_tag = X86_BUS_SPACE_MEM;
|
||||
sc->vga_fb_handle = KERNBASE + VGA_MEM_BASE;
|
||||
sc->vga_reg_tag = X86_BUS_SPACE_IO;
|
||||
sc->vga_reg_handle = VGA_REG_BASE;
|
||||
#elif defined(__ia64__)
|
||||
sc->vga_fb_tag = IA64_BUS_SPACE_MEM;
|
||||
sc->vga_fb_handle = IA64_PHYS_TO_RR6(VGA_MEM_BASE);
|
||||
sc->vga_reg_tag = IA64_BUS_SPACE_IO;
|
||||
sc->vga_reg_handle = VGA_REG_BASE;
|
||||
#else
|
||||
# error "Architecture not yet supported!"
|
||||
#endif
|
||||
|
||||
TUNABLE_INT_FETCH("hw.vga.textmode", &textmode);
|
||||
if (textmode) {
|
||||
vd->vd_flags |= VDF_TEXTMODE;
|
||||
vd->vd_width = 80;
|
||||
vd->vd_height = 25;
|
||||
} else {
|
||||
vd->vd_width = VT_VGA_WIDTH;
|
||||
vd->vd_height = VT_VGA_HEIGHT;
|
||||
}
|
||||
vga_initialize(vd, textmode);
|
||||
|
||||
return (CN_INTERNAL);
|
||||
}
|
220
sys/dev/vt/hw/vga/vga_reg.h
Normal file
220
sys/dev/vt/hw/vga/vga_reg.h
Normal file
@ -0,0 +1,220 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _DEV_VT_HW_VGA_VGA_REG_H_
|
||||
#define _DEV_VT_HW_VGA_VGA_REG_H_
|
||||
|
||||
/*
|
||||
* The VGA adapter uses two I/O port blocks. One of these blocks, the CRT
|
||||
* controller registers, can be located either at 0x3B0 or at 0x3D0 in I/O
|
||||
* port space. This allows compatibility with the monochrome adapter, which
|
||||
* has the CRT controller registers at 0x3B0.
|
||||
*
|
||||
* It is assumed that compatibility with the monochrome adapter is not of
|
||||
* interest anymore. As such, the CRT controller can be located at 0x3D0 in
|
||||
* I/O port space unconditionally. This means that the 2 I/O blocks are
|
||||
* always adjacent and can therefore be treated as a single logical I/O port
|
||||
* range. In practical terms: there only has to be a single tag and handle
|
||||
* to access all registers.
|
||||
*
|
||||
* The following definitions are taken from or inspired by:
|
||||
* Programmer's Guide to the EGA, VGA, and Super VGA Cards -- 3rd ed.,
|
||||
* Richard F. Ferraro, Addison-Wesley, ISBN 0-201-62490-7
|
||||
*/
|
||||
|
||||
#define VGA_MEM_BASE 0xA0000
|
||||
#define VGA_MEM_SIZE 0x10000
|
||||
#define VGA_REG_BASE 0x3c0
|
||||
#define VGA_REG_SIZE 0x10+0x0c
|
||||
|
||||
/* Attribute controller registers. */
|
||||
#define VGA_AC_WRITE 0x00
|
||||
#define VGA_AC_READ 0x01
|
||||
#define VGA_AC_PALETTE(x) (x) /* 0 <= x <= 15 */
|
||||
#define VGA_AC_PAL_SR 0x20 /* Secondary red */
|
||||
#define VGA_AC_PAL_SG 0x10 /* Secondary green */
|
||||
#define VGA_AC_PAL_SB 0x08 /* Secondary blue */
|
||||
#define VGA_AC_PAL_R 0x04 /* Red */
|
||||
#define VGA_AC_PAL_G 0x02 /* Green */
|
||||
#define VGA_AC_PAL_B 0x01 /* Blue */
|
||||
#define VGA_AC_MODE_CONTROL (32+16)
|
||||
#define VGA_AC_MC_IPS 0x80 /* Internal palette size */
|
||||
#define VGA_AC_MC_PCS 0x40 /* Pixel clock select */
|
||||
#define VGA_AC_MC_PPC 0x20 /* Pixel panning compat. */
|
||||
#define VGA_AC_MC_BI 0x08 /* Blink/intensity */
|
||||
#define VGA_AC_MC_ELG 0x04 /* Enable line graphics cc. */
|
||||
#define VGA_AC_MC_DT 0x02 /* Display type */
|
||||
#define VGA_AC_MC_GA 0x01 /* Graphics/alphanumeric */
|
||||
#define VGA_AC_OVERSCAN_COLOR (32+17)
|
||||
#define VGA_AC_COLOR_PLANE_ENABLE (32+18)
|
||||
#define VGA_AC_HORIZ_PIXEL_PANNING (32+19)
|
||||
#define VGA_AC_COLOR_SELECT (32+20)
|
||||
#define VGA_AC_CS_C67 0x0C /* Color reg. addr. bits 6+7 */
|
||||
#define VGA_AC_CS_C45 0x03 /* Color reg. addr. bits 4+5 */
|
||||
|
||||
/* General registers. */
|
||||
#define VGA_GEN_MISC_OUTPUT_W 0x02 /* Write only. */
|
||||
#define VGA_GEN_MISC_OUTPUT_R 0x0c /* Read only. */
|
||||
#define VGA_GEN_MO_VSP 0x80 /* Vertical sync. polarity */
|
||||
#define VGA_GEN_MO_HSP 0x40 /* Horiz. sync. polarity */
|
||||
#define VGA_GEN_MO_PB 0x20 /* Page bit for odd/even */
|
||||
#define VGA_GEN_MO_CS 0x0C /* Clock select */
|
||||
#define VGA_GEN_MO_ER 0x02 /* Enable RAM */
|
||||
#define VGA_GEN_MO_IOA 0x01 /* Input/output address */
|
||||
#define VGA_GEN_INPUT_STAT_0 0x02 /* Read only. */
|
||||
#define VGA_GEN_FEATURE_CTRL_W 0x1a /* Write only. */
|
||||
#define VGA_GEN_FEATURE_CTRL_R 0x0a /* Read only. */
|
||||
#define VGA_GEN_INPUT_STAT_1 0x1a /* Read only. */
|
||||
#define VGA_GEN_IS1_VR 0x08 /* Vertical retrace */
|
||||
#define VGA_GEN_IS1_DE 0x01 /* Display enable not */
|
||||
|
||||
/* Sequencer registers. */
|
||||
#define VGA_SEQ_ADDRESS 0x04
|
||||
#define VGA_SEQ_RESET 0
|
||||
#define VGA_SEQ_RST_SR 0x02 /* Synchronous reset */
|
||||
#define VGA_SEQ_RST_NAR 0x01 /* No async. reset */
|
||||
#define VGA_SEQ_CLOCKING_MODE 1
|
||||
#define VGA_SEQ_CM_SO 0x20 /* Screen off */
|
||||
#define VGA_SEQ_CM_S4 0x10 /* Shift four */
|
||||
#define VGA_SEQ_CM_DC 0x08 /* Dot clock */
|
||||
#define VGA_SEQ_CM_SL 0x04 /* Shift load */
|
||||
#define VGA_SEQ_CM_89 0x01 /* 8/9 Dot clocks */
|
||||
#define VGA_SEQ_MAP_MASK 2
|
||||
#define VGA_SEQ_MM_EM3 0x08 /* Enable memory plane 3 */
|
||||
#define VGA_SEQ_MM_EM2 0x04 /* Enable memory plane 2 */
|
||||
#define VGA_SEQ_MM_EM1 0x02 /* Enable memory plane 1 */
|
||||
#define VGA_SEQ_MM_EM0 0x01 /* Enable memory plane 0 */
|
||||
#define VGA_SEQ_CHAR_MAP_SELECT 3
|
||||
#define VGA_SEQ_CMS_SAH 0x20 /* Char. A (bit 2) */
|
||||
#define VGA_SEQ_CMS_SBH 0x10 /* Char. B (bit 2) */
|
||||
#define VGA_SEQ_CMS_SA 0x0C /* Char. A (bit 0+1) */
|
||||
#define VGA_SEQ_CMS_SB 0x03 /* Char. B (bit 0+1) */
|
||||
#define VGA_SEQ_MEMORY_MODE 4
|
||||
#define VGA_SEQ_MM_C4 0x08 /* Chain four */
|
||||
#define VGA_SEQ_MM_OE 0x04 /* Odd/even */
|
||||
#define VGA_SEQ_MM_EM 0x02 /* Extended memory */
|
||||
#define VGA_SEQ_DATA 0x05
|
||||
|
||||
/* Color registers. */
|
||||
#define VGA_PEL_MASK 0x06
|
||||
#define VGA_PEL_ADDR_RD_MODE 0x07 /* Write only. */
|
||||
#define VGA_DAC_STATE 0x07 /* Read only. */
|
||||
#define VGA_PEL_ADDR_WR_MODE 0x08
|
||||
#define VGA_PEL_DATA 0x09
|
||||
|
||||
/* Graphics controller registers. */
|
||||
#define VGA_GC_ADDRESS 0x0e
|
||||
#define VGA_GC_SET_RESET 0
|
||||
#define VGA_GC_ENABLE_SET_RESET 1
|
||||
#define VGA_GC_COLOR_COMPARE 2
|
||||
#define VGA_GC_DATA_ROTATE 3
|
||||
#define VGA_GC_DR_FS_XOR 0x18 /* Function select - XOR */
|
||||
#define VGA_GC_DR_FS_OR 0x10 /* Function select - OR */
|
||||
#define VGA_GC_DR_FS_AND 0x08 /* Function select - AND */
|
||||
#define VGA_GC_DR_RC 0x07 /* Rotate count */
|
||||
#define VGA_GC_READ_MAP_SELECT 4
|
||||
#define VGA_GC_MODE 5
|
||||
#define VGA_GC_MODE_SR 0x60 /* Shift register */
|
||||
#define VGA_GC_MODE_OE 0x10 /* Odd/even */
|
||||
#define VGA_GC_MODE_RM 0x08 /* Read mode */
|
||||
#define VGA_GC_MODE_WM 0x03 /* Write mode */
|
||||
#define VGA_GC_MISCELLANEOUS 6
|
||||
#define VGA_GC_MISC_MM 0x0C /* memory map */
|
||||
#define VGA_GC_MISC_COE 0x02 /* Chain odd/even */
|
||||
#define VGA_GC_MISC_GA 0x01 /* Graphics/text mode */
|
||||
#define VGA_GC_COLOR_DONT_CARE 7
|
||||
#define VGA_GC_BIT_MASK 8
|
||||
#define VGA_GC_DATA 0x0f
|
||||
|
||||
/* CRT controller registers. */
|
||||
#define VGA_CRTC_ADDRESS 0x14
|
||||
#define VGA_CRTC_HORIZ_TOTAL 0
|
||||
#define VGA_CRTC_HORIZ_DISP_END 1
|
||||
#define VGA_CRTC_START_HORIZ_BLANK 2
|
||||
#define VGA_CRTC_END_HORIZ_BLANK 3
|
||||
#define VGA_CRTC_EHB_CR 0x80 /* Compatible read */
|
||||
#define VGA_CRTC_EHB_DES 0x60 /* Display enable skew */
|
||||
#define VGA_CRTC_EHB_EHB 0x1F /* End horizontal blank */
|
||||
#define VGA_CRTC_START_HORIZ_RETRACE 4
|
||||
#define VGA_CRTC_END_HORIZ_RETRACE 5
|
||||
#define VGA_CRTC_EHR_EHB 0x80 /* End horizontal blanking */
|
||||
#define VGA_CRTC_EHR_HRD 0x60 /* Horizontal retrace delay */
|
||||
#define VGA_CRTC_EHR_EHR 0x1F /* End horizontal retrace */
|
||||
#define VGA_CRTC_VERT_TOTAL 6
|
||||
#define VGA_CRTC_OVERFLOW 7
|
||||
#define VGA_CRTC_OF_VRS9 0x80 /* Vertical retrace start */
|
||||
#define VGA_CRTC_OF_VDE9 0x40 /* Vertical disp. enable end */
|
||||
#define VGA_CRTC_OF_VT9 0x20 /* Vertical total (bit 9) */
|
||||
#define VGA_CRTC_OF_LC8 0x10 /* Line compare */
|
||||
#define VGA_CRTC_OF_VBS8 0x08 /* Start vertical blanking */
|
||||
#define VGA_CRTC_OF_VRS8 0x04 /* Vertical retrace start */
|
||||
#define VGA_CRTC_OF_VDE8 0x02 /* Vertical disp. enable end */
|
||||
#define VGA_CRTC_OF_VT8 0x01 /* Vertical total (bit 8) */
|
||||
#define VGA_CRTC_PRESET_ROW_SCAN 8
|
||||
#define VGA_CRTC_PRS_BP 0x60 /* Byte panning */
|
||||
#define VGA_CRTC_PRS_PRS 0x1F /* Preset row scan */
|
||||
#define VGA_CRTC_MAX_SCAN_LINE 9
|
||||
#define VGA_CRTC_MSL_2T4 0x80 /* 200-to-400 line conversion */
|
||||
#define VGA_CRTC_MSL_LC9 0x40 /* Line compare (bit 9) */
|
||||
#define VGA_CRTC_MSL_VBS9 0x20 /* Start vertical blanking */
|
||||
#define VGA_CRTC_MSL_MSL 0x1F /* Maximum scan line */
|
||||
#define VGA_CRTC_CURSOR_START 10
|
||||
#define VGA_CRTC_CS_COO 0x20 /* Cursor on/off */
|
||||
#define VGA_CRTC_CS_CS 0x1F /* Cursor start */
|
||||
#define VGA_CRTC_CURSOR_END 11
|
||||
#define VGA_CRTC_CE_CSK 0x60 /* Cursor skew */
|
||||
#define VGA_CRTC_CE_CE 0x1F /* Cursor end */
|
||||
#define VGA_CRTC_START_ADDR_HIGH 12
|
||||
#define VGA_CRTC_START_ADDR_LOW 13
|
||||
#define VGA_CRTC_CURSOR_LOC_HIGH 14
|
||||
#define VGA_CRTC_CURSOR_LOC_LOW 15
|
||||
#define VGA_CRTC_VERT_RETRACE_START 16
|
||||
#define VGA_CRTC_VERT_RETRACE_END 17
|
||||
#define VGA_CRTC_VRE_PR 0x80 /* Protect register 0-7 */
|
||||
#define VGA_CRTC_VRE_BW 0x40 /* Bandwidth */
|
||||
#define VGA_CRTC_VRE_VRE 0x1F /* Vertical retrace end */
|
||||
#define VGA_CRTC_VERT_DISPLAY_END 18
|
||||
#define VGA_CRTC_OFFSET 19
|
||||
#define VGA_CRTC_UNDERLINE_LOC 20
|
||||
#define VGA_CRTC_UL_DW 0x40 /* Double word mode */
|
||||
#define VGA_CRTC_UL_CB4 0x20 /* Count by four */
|
||||
#define VGA_CRTC_UL_UL 0x1F /* Underline location */
|
||||
#define VGA_CRTC_START_VERT_BLANK 21
|
||||
#define VGA_CRTC_END_VERT_BLANK 22
|
||||
#define VGA_CRTC_MODE_CONTROL 23
|
||||
#define VGA_CRTC_MC_HR 0x80 /* hardware reset */
|
||||
#define VGA_CRTC_MC_WB 0x40 /* Word/byte mode */
|
||||
#define VGA_CRTC_MC_AW 0x20 /* Address wrap */
|
||||
#define VGA_CRTC_MC_CBT 0x08 /* Count by two */
|
||||
#define VGA_CRTC_MC_HRS 0x04 /* Horizontal retrace select */
|
||||
#define VGA_CRTC_MC_SRS 0x02 /* Select row scan counter */
|
||||
#define VGA_CRTC_MC_CMS 0x01 /* Compatibility mode support */
|
||||
#define VGA_CRTC_LINE_COMPARE 24
|
||||
#define VGA_CRTC_DATA 0x15
|
||||
|
||||
#endif /* !_DEV_VT_HW_VGA_VGA_REG_H_ */
|
212
sys/dev/vt/hw/xboxfb/xboxfb.c
Normal file
212
sys/dev/vt/hw/xboxfb/xboxfb.c
Normal file
@ -0,0 +1,212 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Rink Springer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Ed Schouten
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/xbox.h>
|
||||
|
||||
struct xbox_softc {
|
||||
bus_space_tag_t xbox_fb_tag;
|
||||
bus_space_handle_t xbox_fb_handle;
|
||||
};
|
||||
|
||||
/* Convenience macros. */
|
||||
#define MEM_WRITE4(sc, ofs, val) \
|
||||
bus_space_write_4(sc->xbox_fb_tag, sc->xbox_fb_handle, ofs, val)
|
||||
|
||||
#define VT_XBOX_WIDTH 640
|
||||
#define VT_XBOX_HEIGHT 480
|
||||
|
||||
static vd_init_t xbox_init;
|
||||
static vd_blank_t xbox_blank;
|
||||
static vd_bitbltchr_t xbox_bitbltchr;
|
||||
|
||||
static const struct vt_driver vt_xbox_driver = {
|
||||
.vd_init = xbox_init,
|
||||
.vd_blank = xbox_blank,
|
||||
.vd_bitbltchr = xbox_bitbltchr,
|
||||
.vd_priority = VD_PRIORITY_GENERIC+1,
|
||||
};
|
||||
|
||||
static struct xbox_softc xbox_conssoftc;
|
||||
VT_CONSDEV_DECLARE(vt_xbox_driver, PIXEL_WIDTH(VT_XBOX_WIDTH),
|
||||
PIXEL_HEIGHT(VT_XBOX_HEIGHT), &xbox_conssoftc);
|
||||
|
||||
static const uint32_t colormap[] = {
|
||||
0x00000000, /* Black */
|
||||
0x00ff0000, /* Red */
|
||||
0x0000ff00, /* Green */
|
||||
0x00c0c000, /* Brown */
|
||||
0x000000ff, /* Blue */
|
||||
0x00c000c0, /* Magenta */
|
||||
0x0000c0c0, /* Cyan */
|
||||
0x00c0c0c0, /* Light grey */
|
||||
0x00808080, /* Dark grey */
|
||||
0x00ff8080, /* Light red */
|
||||
0x0080ff80, /* Light green */
|
||||
0x00ffff80, /* Yellow */
|
||||
0x008080ff, /* Light blue */
|
||||
0x00ff80ff, /* Light magenta */
|
||||
0x0080ffff, /* Light cyan */
|
||||
0x00ffffff, /* White */
|
||||
};
|
||||
|
||||
static void
|
||||
xbox_blank(struct vt_device *vd, term_color_t color)
|
||||
{
|
||||
struct xbox_softc *sc = vd->vd_softc;
|
||||
u_int ofs;
|
||||
uint32_t c;
|
||||
|
||||
c = colormap[color];
|
||||
for (ofs = 0; ofs < (VT_XBOX_WIDTH * VT_XBOX_HEIGHT) * 4; ofs += 4)
|
||||
MEM_WRITE4(sc, ofs, c);
|
||||
}
|
||||
|
||||
static void
|
||||
xbox_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
|
||||
int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
|
||||
unsigned int height, term_color_t fg, term_color_t bg)
|
||||
{
|
||||
struct xbox_softc *sc = vd->vd_softc;
|
||||
u_long line;
|
||||
uint32_t fgc, bgc;
|
||||
int c;
|
||||
uint8_t b, m;
|
||||
|
||||
fgc = colormap[fg];
|
||||
bgc = colormap[bg];
|
||||
|
||||
/* Don't try to put off screen pixels */
|
||||
if (((left + width) > info->fb_width) || ((top + height) >
|
||||
info->fb_height))
|
||||
return;
|
||||
|
||||
line = (VT_XBOX_WIDTH * top + left) * 4;
|
||||
for (; height > 0; height--) {
|
||||
for (c = 0; c < width; c++) {
|
||||
if (c % 8 == 0)
|
||||
b = *src++;
|
||||
else
|
||||
b <<= 1;
|
||||
if (mask != NULL) {
|
||||
if (c % 8 == 0)
|
||||
m = *mask++;
|
||||
else
|
||||
m <<= 1;
|
||||
/* Skip pixel write, if mask has no bit set. */
|
||||
if ((m & 0x80) == 0)
|
||||
continue;
|
||||
}
|
||||
MEM_WRITE4(sc, line + c * 4, b & 0x80 ? fgc : bgc);
|
||||
}
|
||||
line += VT_XBOX_WIDTH * 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xbox_initialize(struct vt_device *vd)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* We must make a mapping from video framebuffer memory
|
||||
* to real. This is very crude: we map the entire
|
||||
* videomemory to PAGE_SIZE! Since our kernel lives at
|
||||
* it's relocated address range (0xc0xxxxxx), it won't
|
||||
* care.
|
||||
*
|
||||
* We use address PAGE_SIZE and up so we can still trap
|
||||
* NULL pointers. Once the real init is called, the
|
||||
* mapping will be done via the OS and stored in a more
|
||||
* sensible location ... but since we're not fully
|
||||
* initialized, this is our only way to go :-(
|
||||
*/
|
||||
for (i = 0; i < (XBOX_FB_SIZE / PAGE_SIZE); i++) {
|
||||
pmap_kenter(((i + 1) * PAGE_SIZE),
|
||||
XBOX_FB_START + (i * PAGE_SIZE));
|
||||
}
|
||||
pmap_kenter((i + 1) * PAGE_SIZE,
|
||||
XBOX_FB_START_PTR - XBOX_FB_START_PTR % PAGE_SIZE);
|
||||
|
||||
/* Ensure the framebuffer is where we want it to be. */
|
||||
*(uint32_t *)((i + 1) * PAGE_SIZE + XBOX_FB_START_PTR % PAGE_SIZE) =
|
||||
XBOX_FB_START;
|
||||
|
||||
/* Clear the screen. */
|
||||
xbox_blank(vd, TC_BLACK);
|
||||
}
|
||||
|
||||
static int
|
||||
xbox_init(struct vt_device *vd)
|
||||
{
|
||||
struct xbox_softc *sc = vd->vd_softc;
|
||||
|
||||
if (!arch_i386_is_xbox)
|
||||
return (CN_DEAD);
|
||||
|
||||
sc->xbox_fb_tag = I386_BUS_SPACE_MEM;
|
||||
sc->xbox_fb_handle = PAGE_SIZE;
|
||||
|
||||
vd->vd_width = VT_XBOX_WIDTH;
|
||||
vd->vd_height = VT_XBOX_HEIGHT;
|
||||
|
||||
xbox_initialize(vd);
|
||||
|
||||
return (CN_INTERNAL);
|
||||
}
|
||||
|
||||
static void
|
||||
xbox_remap(void *unused)
|
||||
{
|
||||
|
||||
if (!arch_i386_is_xbox)
|
||||
return;
|
||||
|
||||
xbox_conssoftc.xbox_fb_handle =
|
||||
(bus_space_handle_t)pmap_mapdev(XBOX_FB_START, XBOX_FB_SIZE);
|
||||
}
|
||||
|
||||
SYSINIT(xboxfb, SI_SUB_DRIVERS, SI_ORDER_ANY, xbox_remap, NULL);
|
641
sys/dev/vt/logo/logo_freebsd.c
Normal file
641
sys/dev/vt/logo/logo_freebsd.c
Normal file
@ -0,0 +1,641 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Ed Schouten under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
unsigned int vt_logo_width = 257;
|
||||
unsigned int vt_logo_height = 219;
|
||||
unsigned int vt_logo_depth = 1;
|
||||
|
||||
unsigned char vt_logo_image[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xfe,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff,
|
||||
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xff,
|
||||
0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff,
|
||||
0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
|
||||
0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x07,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff,
|
||||
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1f, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff,
|
||||
0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x7f,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x81, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0f, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff,
|
||||
0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf0, 0x7f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff,
|
||||
0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x07, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8,
|
||||
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x7f, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x83, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1f, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1f, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x04, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xc7, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff,
|
||||
0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xfc,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfc, 0x7f, 0xff, 0xff, 0xf1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f,
|
||||
0xff, 0xff, 0xf3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xe3,
|
||||
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xc7, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xc7, 0xff, 0xff, 0xc7, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe1,
|
||||
0xff, 0xff, 0x8f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0x0f,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0x07, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfc, 0x0f, 0xfe, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x01, 0xf8, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x07,
|
||||
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x07, 0xfc, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfc, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1f,
|
||||
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xfe, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
|
||||
0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x07,
|
||||
0xff, 0xf0, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff,
|
||||
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xfe, 0x00,
|
||||
0x07, 0xff, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff,
|
||||
0xe0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x1f,
|
||||
0xf8, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00,
|
||||
0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x03, 0xfc, 0x00, 0xff,
|
||||
0xe0, 0xff, 0xc0, 0x1f, 0x80, 0x0f, 0xfc, 0x00, 0x00, 0x3f, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x1f, 0xc0,
|
||||
0x1f, 0x00, 0x01, 0xff, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3f, 0x00, 0x00, 0x7e, 0x01, 0xfc, 0x00, 0x07, 0x80, 0x3e, 0x00, 0x00,
|
||||
0x7f, 0x80, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
|
||||
0x3f, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1f, 0xc0, 0x00,
|
||||
0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x3f, 0x03, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x7c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x1f, 0x03, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x3e, 0x00, 0x00, 0x07, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x1f, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
|
||||
0x03, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
|
||||
0x1f, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0xf8, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x1f, 0x03, 0xe0,
|
||||
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x00, 0x07, 0xfc, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f,
|
||||
0xc0, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x1f, 0x03, 0xe0, 0x00, 0x00, 0x00,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff,
|
||||
0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 0x00,
|
||||
0xf8, 0x00, 0x00, 0x1f, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
|
||||
0x00, 0x7e, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f,
|
||||
0xff, 0xf0, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0xf8, 0x00, 0x00,
|
||||
0x3f, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xfc, 0x00,
|
||||
0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0xf8, 0x00, 0x00, 0x3f, 0x03, 0xf8,
|
||||
0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff,
|
||||
0xff, 0xc0, 0x00, 0xf8, 0x00, 0x00, 0x7e, 0x01, 0xfc, 0x00, 0x00, 0x00,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00, 0x03, 0xfc, 0x07,
|
||||
0xf8, 0x07, 0xfe, 0x03, 0xff, 0x00, 0x00, 0xff, 0xc0, 0x3f, 0xe0, 0x00,
|
||||
0xfc, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
|
||||
0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00, 0x07, 0xf0, 0x01, 0xf8, 0x0f, 0xf0,
|
||||
0x00, 0x7f, 0x80, 0x01, 0xfe, 0x00, 0x0f, 0xf0, 0x00, 0xfc, 0x00, 0x01,
|
||||
0xfc, 0x00, 0xff, 0x80, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x07, 0xe0, 0x00, 0xf8, 0x1f, 0xc0, 0x00, 0x3f, 0xc0,
|
||||
0x03, 0xfc, 0x00, 0x03, 0xf8, 0x00, 0xfe, 0x00, 0x0f, 0xfc, 0x00, 0x7f,
|
||||
0xe0, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xfe, 0x00, 0x00,
|
||||
0x0f, 0xc0, 0x00, 0x78, 0x1f, 0x80, 0x00, 0x0f, 0xc0, 0x03, 0xf0, 0x00,
|
||||
0x01, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xf0, 0x00, 0x00,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xff, 0x00, 0x00, 0x0f, 0x80, 0x00,
|
||||
0x00, 0x3f, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0xfc, 0x00,
|
||||
0xff, 0xff, 0xff, 0xfc, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x3e, 0x00, 0x00,
|
||||
0x00, 0x0f, 0x80, 0xff, 0xff, 0xfc, 0x0f, 0x80, 0x00, 0x00, 0x7e, 0x00,
|
||||
0x00, 0x03, 0xf0, 0x07, 0xe0, 0x00, 0x00, 0x7e, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x07, 0xff, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80,
|
||||
0xff, 0xff, 0xfc, 0x1f, 0x80, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x03, 0xf0,
|
||||
0x0f, 0xc0, 0x00, 0x00, 0x7e, 0x00, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01,
|
||||
0xff, 0xc0, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xff, 0xff, 0xfe,
|
||||
0x1f, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00,
|
||||
0x00, 0x3e, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x7f, 0xf0, 0x00,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xff, 0xff, 0xfc, 0x1f, 0x00, 0x00,
|
||||
0x00, 0xfc, 0x00, 0x00, 0x01, 0xf8, 0x1f, 0x80, 0x00, 0x00, 0x1f, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0xfc, 0x00, 0x3e, 0x00, 0x00,
|
||||
0x00, 0x0f, 0x80, 0xff, 0xff, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x00,
|
||||
0x00, 0x00, 0xf8, 0x1f, 0x80, 0x00, 0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x07, 0xf0, 0x00, 0x07, 0xff, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80,
|
||||
0xfe, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x01, 0xf8,
|
||||
0x1f, 0x80, 0x00, 0x00, 0x1f, 0x00, 0xf8, 0x00, 0x00, 0x03, 0xf8, 0x00,
|
||||
0x01, 0xff, 0x80, 0x3e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0xfc, 0x00, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff,
|
||||
0xff, 0xff, 0x80, 0xf8, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x7f, 0xc0,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
|
||||
0x01, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80,
|
||||
0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0xe0, 0x3e, 0x00, 0x00,
|
||||
0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x01, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0xf8, 0x00, 0x00,
|
||||
0x00, 0xfc, 0x00, 0x00, 0x0f, 0xf0, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf8,
|
||||
0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00,
|
||||
0x00, 0x03, 0xf8, 0x3e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff,
|
||||
0xff, 0xff, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x01, 0xf8,
|
||||
0x3e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x00,
|
||||
0xf8, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00,
|
||||
0x00, 0x3e, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xfc, 0x00,
|
||||
0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x00, 0x7c, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7e, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x00, 0x7c, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc,
|
||||
0x3e, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
|
||||
0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf8, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00,
|
||||
0x01, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7e, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
|
||||
0x00, 0x7c, 0x00, 0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x03, 0xf0, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x3e, 0x00, 0x00, 0x07, 0xe0, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00,
|
||||
0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x01, 0xfc,
|
||||
0x3e, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
|
||||
0x00, 0x1f, 0x80, 0x00, 0x0c, 0x00, 0x03, 0xf0, 0x00, 0x01, 0x80, 0x00,
|
||||
0xf8, 0x00, 0x00, 0x01, 0xf8, 0x70, 0x00, 0x03, 0xf8, 0x3e, 0x00, 0x00,
|
||||
0x1f, 0xc0, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0xc0,
|
||||
0x00, 0x3e, 0x00, 0x03, 0xfc, 0x00, 0x03, 0xc0, 0x00, 0xf8, 0x00, 0x00,
|
||||
0x03, 0xf8, 0xfc, 0x00, 0x07, 0xf8, 0x3f, 0x00, 0x00, 0x7f, 0x80, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x7e, 0x00,
|
||||
0x01, 0xfe, 0x00, 0x0f, 0xe0, 0x00, 0xf8, 0x00, 0x00, 0x07, 0xf0, 0xff,
|
||||
0x80, 0x0f, 0xf0, 0x3f, 0x00, 0x01, 0xff, 0x00, 0x00, 0xfc, 0x00, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x00, 0x07, 0xfe, 0x03, 0xfe, 0x00, 0x00, 0xff, 0xc0,
|
||||
0x3f, 0xc0, 0x00, 0xf8, 0x00, 0x00, 0x3f, 0xe0, 0xff, 0xf8, 0x7f, 0xe0,
|
||||
0x3f, 0x80, 0x1f, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00,
|
||||
0x00, 0x03, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff,
|
||||
0xf8, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||
0xff, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0x80, 0x7f, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xe0, 0x00, 0x00,
|
||||
0xfc, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0x00,
|
||||
0x00, 0x0f, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f,
|
||||
0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x78, 0x00, 0x00,
|
||||
0x1f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff,
|
||||
0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xfc, 0x00,
|
||||
0x1f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00,
|
||||
0x3f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
};
|
410
sys/dev/vt/vt.h
Normal file
410
sys/dev/vt/vt.h
Normal file
@ -0,0 +1,410 @@
|
||||
/*-
|
||||
* Copyright (c) 2009, 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Ed Schouten under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Portions of this software were developed by Oleksandr Rybalko
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _DEV_VT_VT_H_
|
||||
#define _DEV_VT_VT_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/_lock.h>
|
||||
#include <sys/_mutex.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/kbio.h>
|
||||
#include <sys/mouse.h>
|
||||
#include <sys/terminal.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include "opt_syscons.h"
|
||||
|
||||
#ifndef VT_MAXWINDOWS
|
||||
#ifdef MAXCONS
|
||||
#define VT_MAXWINDOWS MAXCONS
|
||||
#else
|
||||
#define VT_MAXWINDOWS 12
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef VT_ALT_TO_ESC_HACK
|
||||
#define VT_ALT_TO_ESC_HACK 1
|
||||
#endif
|
||||
|
||||
#define VT_CONSWINDOW 0
|
||||
|
||||
#if defined(SC_TWOBUTTON_MOUSE) || defined(VT_TWOBUTTON_MOUSE)
|
||||
#define VT_MOUSE_PASTEBUTTON MOUSE_BUTTON3DOWN /* right button */
|
||||
#define VT_MOUSE_EXTENDBUTTON MOUSE_BUTTON2DOWN /* not really used */
|
||||
#else
|
||||
#define VT_MOUSE_PASTEBUTTON MOUSE_BUTTON2DOWN /* middle button */
|
||||
#define VT_MOUSE_EXTENDBUTTON MOUSE_BUTTON3DOWN /* right button */
|
||||
#endif /* defined(SC_TWOBUTTON_MOUSE) || defined(VT_TWOBUTTON_MOUSE) */
|
||||
|
||||
#define SC_DRIVER_NAME "vt"
|
||||
#define DPRINTF(_l, ...) if (vt_debug > (_l)) printf( __VA_ARGS__ )
|
||||
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
|
||||
|
||||
#define VT_SYSCTL_INT(_name, _default, _descr) \
|
||||
static int vt_##_name = _default; \
|
||||
SYSCTL_INT(_kern_vt, OID_AUTO, _name, CTLFLAG_RW, &vt_##_name, _default,\
|
||||
_descr); \
|
||||
TUNABLE_INT("kern.vt." #_name, &vt_##_name);
|
||||
|
||||
struct vt_driver;
|
||||
|
||||
void vt_allocate(struct vt_driver *, void *);
|
||||
void vt_resume(void);
|
||||
void vt_suspend(void);
|
||||
|
||||
typedef unsigned int vt_axis_t;
|
||||
|
||||
/*
|
||||
* List of locks
|
||||
* (d) locked by vd_lock
|
||||
* (b) locked by vb_lock
|
||||
* (G) locked by Giant
|
||||
* (u) unlocked, locked by higher levels
|
||||
* (c) const until freeing
|
||||
* (?) yet to be determined
|
||||
*/
|
||||
|
||||
/*
|
||||
* Per-device datastructure.
|
||||
*/
|
||||
|
||||
struct vt_device {
|
||||
struct vt_window *vd_windows[VT_MAXWINDOWS]; /* (c) Windows. */
|
||||
struct vt_window *vd_curwindow; /* (d) Current window. */
|
||||
struct vt_window *vd_savedwindow;/* (?) Saved for suspend. */
|
||||
struct vt_window *vd_markedwin; /* (?) Copy/paste buf owner. */
|
||||
const struct vt_driver *vd_driver; /* (c) Graphics driver. */
|
||||
void *vd_softc; /* (u) Driver data. */
|
||||
uint16_t vd_mx; /* (?) Mouse X. */
|
||||
uint16_t vd_my; /* (?) Mouse Y. */
|
||||
vt_axis_t vd_mdirtyx; /* (?) Screen width. */
|
||||
vt_axis_t vd_mdirtyy; /* (?) Screen height. */
|
||||
uint32_t vd_mstate; /* (?) Mouse state. */
|
||||
term_pos_t vd_offset; /* (?) Pixel offset. */
|
||||
vt_axis_t vd_width; /* (?) Screen width. */
|
||||
vt_axis_t vd_height; /* (?) Screen height. */
|
||||
struct mtx vd_lock; /* Per-device lock. */
|
||||
struct cv vd_winswitch; /* (d) Window switch notify. */
|
||||
struct callout vd_timer; /* (d) Display timer. */
|
||||
int vd_flags; /* (d) Device flags. */
|
||||
#define VDF_TEXTMODE 0x01 /* Do text mode rendering. */
|
||||
#define VDF_SPLASH 0x02 /* Splash screen active. */
|
||||
#define VDF_ASYNC 0x04 /* vt_timer() running. */
|
||||
#define VDF_INVALID 0x08 /* Entire screen should be re-rendered. */
|
||||
#define VDF_DEAD 0x10 /* Early probing found nothing. */
|
||||
#define VDF_INITIALIZED 0x20 /* vtterm_cnprobe already done. */
|
||||
#define VDF_MOUSECURSOR 0x40 /* Mouse cursor visible. */
|
||||
int vd_keyboard; /* (G) Keyboard index. */
|
||||
unsigned int vd_kbstate; /* (?) Device unit. */
|
||||
unsigned int vd_unit; /* (c) Device unit. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Per-window terminal screen buffer.
|
||||
*
|
||||
* Because redrawing is performed asynchronously, the buffer keeps track
|
||||
* of a rectangle that needs to be redrawn (vb_dirtyrect). Because this
|
||||
* approach seemed to cause suboptimal performance (when the top left
|
||||
* and the bottom right of the screen are modified), it also uses a set
|
||||
* of bitmasks to keep track of the rows and columns (mod 64) that have
|
||||
* been modified.
|
||||
*/
|
||||
|
||||
struct vt_bufmask {
|
||||
uint64_t vbm_row, vbm_col;
|
||||
#define VBM_DIRTY UINT64_MAX
|
||||
};
|
||||
|
||||
struct vt_buf {
|
||||
struct mtx vb_lock; /* Buffer lock. */
|
||||
term_pos_t vb_scr_size; /* (b) Screen dimensions. */
|
||||
int vb_flags; /* (b) Flags. */
|
||||
#define VBF_CURSOR 0x1 /* Cursor visible. */
|
||||
#define VBF_STATIC 0x2 /* Buffer is statically allocated. */
|
||||
#define VBF_MTX_INIT 0x4 /* Mutex initialized. */
|
||||
#define VBF_SCROLL 0x8 /* scroll locked mode. */
|
||||
#define VBF_HISTORY_FULL 0x10 /* All rows filled. */
|
||||
int vb_history_size;
|
||||
#define VBF_DEFAULT_HISTORY_SIZE 500
|
||||
int vb_roffset; /* (b) History rows offset. */
|
||||
int vb_curroffset; /* (b) Saved rows offset. */
|
||||
term_pos_t vb_cursor; /* (u) Cursor position. */
|
||||
term_pos_t vb_mark_start; /* (b) Copy region start. */
|
||||
term_pos_t vb_mark_end; /* (b) Copy region end. */
|
||||
int vb_mark_last; /* Last mouse event. */
|
||||
term_rect_t vb_dirtyrect; /* (b) Dirty rectangle. */
|
||||
struct vt_bufmask vb_dirtymask; /* (b) Dirty bitmasks. */
|
||||
term_char_t *vb_buffer; /* (u) Data buffer. */
|
||||
term_char_t **vb_rows; /* (u) Array of rows */
|
||||
};
|
||||
|
||||
void vtbuf_copy(struct vt_buf *, const term_rect_t *, const term_pos_t *);
|
||||
void vtbuf_fill_locked(struct vt_buf *, const term_rect_t *, term_char_t);
|
||||
void vtbuf_init_early(struct vt_buf *);
|
||||
void vtbuf_init(struct vt_buf *, const term_pos_t *);
|
||||
void vtbuf_grow(struct vt_buf *, const term_pos_t *, int);
|
||||
void vtbuf_putchar(struct vt_buf *, const term_pos_t *, term_char_t);
|
||||
void vtbuf_cursor_position(struct vt_buf *, const term_pos_t *);
|
||||
void vtbuf_mouse_cursor_position(struct vt_buf *vb, int col, int row);
|
||||
void vtbuf_cursor_visibility(struct vt_buf *, int);
|
||||
void vtbuf_scroll_mode(struct vt_buf *vb, int yes);
|
||||
void vtbuf_undirty(struct vt_buf *, term_rect_t *, struct vt_bufmask *);
|
||||
void vtbuf_sethistory_size(struct vt_buf *, int);
|
||||
int vtbuf_set_mark(struct vt_buf *vb, int type, int col, int row);
|
||||
int vtbuf_iscursor(struct vt_buf *vb, int row, int col);
|
||||
int vtbuf_get_marked_len(struct vt_buf *vb);
|
||||
void vtbuf_extract_marked(struct vt_buf *vb, term_char_t *buf, int sz);
|
||||
|
||||
#define VTB_MARK_NONE 0
|
||||
#define VTB_MARK_END 1
|
||||
#define VTB_MARK_START 2
|
||||
#define VTB_MARK_WORD 3
|
||||
#define VTB_MARK_ROW 4
|
||||
#define VTB_MARK_EXTEND 5
|
||||
#define VTB_MARK_MOVE 6
|
||||
|
||||
#define VTBUF_SLCK_ENABLE(vb) vtbuf_scroll_mode((vb), 1)
|
||||
#define VTBUF_SLCK_DISABLE(vb) vtbuf_scroll_mode((vb), 0)
|
||||
|
||||
#define VTBUF_MAX_HEIGHT(vb) \
|
||||
((vb)->vb_history_size)
|
||||
#define VTBUF_GET_ROW(vb, r) \
|
||||
((vb)->vb_rows[((vb)->vb_roffset + (r)) % VTBUF_MAX_HEIGHT(vb)])
|
||||
#define VTBUF_GET_FIELD(vb, r, c) \
|
||||
((vb)->vb_rows[((vb)->vb_roffset + (r)) % VTBUF_MAX_HEIGHT(vb)][(c)])
|
||||
#define VTBUF_FIELD(vb, r, c) \
|
||||
((vb)->vb_rows[((vb)->vb_curroffset + (r)) % VTBUF_MAX_HEIGHT(vb)][(c)])
|
||||
#define VTBUF_ISCURSOR(vb, r, c) \
|
||||
vtbuf_iscursor((vb), (r), (c))
|
||||
#define VTBUF_DIRTYROW(mask, row) \
|
||||
((mask)->vbm_row & ((uint64_t)1 << ((row) % 64)))
|
||||
#define VTBUF_DIRTYCOL(mask, col) \
|
||||
((mask)->vbm_col & ((uint64_t)1 << ((col) % 64)))
|
||||
#define VTBUF_SPACE_CHAR (' ' | TC_WHITE << 26 | TC_BLACK << 29)
|
||||
|
||||
#define VHS_SET 0
|
||||
#define VHS_CUR 1
|
||||
#define VHS_END 2
|
||||
int vthistory_seek(struct vt_buf *, int offset, int whence);
|
||||
void vthistory_addlines(struct vt_buf *vb, int offset);
|
||||
void vthistory_getpos(const struct vt_buf *, unsigned int *offset);
|
||||
|
||||
/*
|
||||
* Per-window datastructure.
|
||||
*/
|
||||
|
||||
struct vt_window {
|
||||
struct vt_device *vw_device; /* (c) Device. */
|
||||
struct terminal *vw_terminal; /* (c) Terminal. */
|
||||
struct vt_buf vw_buf; /* (u) Screen buffer. */
|
||||
struct vt_font *vw_font; /* (d) Graphical font. */
|
||||
unsigned int vw_number; /* (c) Window number. */
|
||||
int vw_kbdmode; /* (?) Keyboard mode. */
|
||||
char *vw_kbdsq; /* Escape sequence queue*/
|
||||
unsigned int vw_flags; /* (d) Per-window flags. */
|
||||
#define VWF_BUSY 0x1 /* Busy reconfiguring device. */
|
||||
#define VWF_OPENED 0x2 /* TTY in use. */
|
||||
#define VWF_SCROLL 0x4 /* Keys influence scrollback. */
|
||||
#define VWF_CONSOLE 0x8 /* Kernel message console window. */
|
||||
#define VWF_VTYLOCK 0x10 /* Prevent window switch. */
|
||||
#define VWF_MOUSE_HIDE 0x20 /* Disable mouse events processing. */
|
||||
#define VWF_SWWAIT_REL 0x10000 /* Program wait for VT acquire is done. */
|
||||
#define VWF_SWWAIT_ACQ 0x20000 /* Program wait for VT release is done. */
|
||||
pid_t vw_pid; /* Terminal holding process */
|
||||
struct proc *vw_proc;
|
||||
struct vt_mode vw_smode; /* switch mode */
|
||||
struct callout vw_proc_dead_timer;
|
||||
struct vt_window *vw_switch_to;
|
||||
};
|
||||
|
||||
#define VT_AUTO 0 /* switching is automatic */
|
||||
#define VT_PROCESS 1 /* switching controlled by prog */
|
||||
#define VT_KERNEL 255 /* switching controlled in kernel */
|
||||
|
||||
#define IS_VT_PROC_MODE(vw) ((vw)->vw_smode.mode == VT_PROCESS)
|
||||
|
||||
/*
|
||||
* Per-device driver routines.
|
||||
*
|
||||
* vd_bitbltchr is used when the driver operates in graphics mode, while
|
||||
* vd_putchar is used when the driver operates in text mode
|
||||
* (VDF_TEXTMODE).
|
||||
*/
|
||||
|
||||
typedef int vd_init_t(struct vt_device *vd);
|
||||
typedef void vd_postswitch_t(struct vt_device *vd);
|
||||
typedef void vd_blank_t(struct vt_device *vd, term_color_t color);
|
||||
typedef void vd_bitbltchr_t(struct vt_device *vd, const uint8_t *src,
|
||||
const uint8_t *mask, int bpl, vt_axis_t top, vt_axis_t left,
|
||||
unsigned int width, unsigned int height, term_color_t fg, term_color_t bg);
|
||||
typedef void vd_putchar_t(struct vt_device *vd, term_char_t,
|
||||
vt_axis_t top, vt_axis_t left, term_color_t fg, term_color_t bg);
|
||||
|
||||
struct vt_driver {
|
||||
/* Console attachment. */
|
||||
vd_init_t *vd_init;
|
||||
|
||||
/* Drawing. */
|
||||
vd_blank_t *vd_blank;
|
||||
vd_bitbltchr_t *vd_bitbltchr;
|
||||
|
||||
/* Text mode operation. */
|
||||
vd_putchar_t *vd_putchar;
|
||||
|
||||
/* Update display setting on vt switch. */
|
||||
vd_postswitch_t *vd_postswitch;
|
||||
|
||||
/* Priority to know which one can override */
|
||||
int vd_priority;
|
||||
#define VD_PRIORITY_DUMB 10
|
||||
#define VD_PRIORITY_GENERIC 100
|
||||
#define VD_PRIORITY_SPECIFIC 1000
|
||||
};
|
||||
|
||||
/*
|
||||
* Console device madness.
|
||||
*
|
||||
* Utility macro to make early vt(4) instances work.
|
||||
*/
|
||||
|
||||
extern const struct terminal_class vt_termclass;
|
||||
void vt_upgrade(struct vt_device *vd);
|
||||
|
||||
#define PIXEL_WIDTH(w) ((w) / 8)
|
||||
#define PIXEL_HEIGHT(h) ((h) / 16)
|
||||
|
||||
#ifndef VT_FB_DEFAULT_WIDTH
|
||||
#define VT_FB_DEFAULT_WIDTH 640
|
||||
#endif
|
||||
#ifndef VT_FB_DEFAULT_HEIGHT
|
||||
#define VT_FB_DEFAULT_HEIGHT 480
|
||||
#endif
|
||||
|
||||
#define VT_CONSDEV_DECLARE(driver, width, height, softc) \
|
||||
static struct terminal driver ## _consterm; \
|
||||
static struct vt_window driver ## _conswindow; \
|
||||
static struct vt_device driver ## _consdev = { \
|
||||
.vd_driver = &driver, \
|
||||
.vd_softc = (softc), \
|
||||
.vd_flags = VDF_INVALID, \
|
||||
.vd_windows = { [VT_CONSWINDOW] = &driver ## _conswindow, }, \
|
||||
.vd_curwindow = &driver ## _conswindow, \
|
||||
.vd_markedwin = NULL, \
|
||||
.vd_kbstate = 0, \
|
||||
}; \
|
||||
static term_char_t driver ## _constextbuf[(width) * \
|
||||
(VBF_DEFAULT_HISTORY_SIZE)]; \
|
||||
static term_char_t *driver ## _constextbufrows[ \
|
||||
VBF_DEFAULT_HISTORY_SIZE]; \
|
||||
static struct vt_window driver ## _conswindow = { \
|
||||
.vw_number = VT_CONSWINDOW, \
|
||||
.vw_flags = VWF_CONSOLE, \
|
||||
.vw_buf = { \
|
||||
.vb_buffer = driver ## _constextbuf, \
|
||||
.vb_rows = driver ## _constextbufrows, \
|
||||
.vb_history_size = VBF_DEFAULT_HISTORY_SIZE, \
|
||||
.vb_curroffset = 0, \
|
||||
.vb_roffset = 0, \
|
||||
.vb_flags = VBF_STATIC, \
|
||||
.vb_mark_start = { \
|
||||
.tp_row = 0, \
|
||||
.tp_col = 0, \
|
||||
}, \
|
||||
.vb_mark_end = { \
|
||||
.tp_row = 0, \
|
||||
.tp_col = 0, \
|
||||
}, \
|
||||
.vb_scr_size = { \
|
||||
.tp_row = height, \
|
||||
.tp_col = width, \
|
||||
}, \
|
||||
}, \
|
||||
.vw_device = &driver ## _consdev, \
|
||||
.vw_terminal = &driver ## _consterm, \
|
||||
.vw_kbdmode = K_XLATE, \
|
||||
}; \
|
||||
TERMINAL_DECLARE_EARLY(driver ## _consterm, vt_termclass, \
|
||||
&driver ## _conswindow); \
|
||||
SYSINIT(vt_early_cons, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY, \
|
||||
vt_upgrade, &driver ## _consdev)
|
||||
|
||||
/*
|
||||
* Fonts.
|
||||
*
|
||||
* Remapping tables are used to map Unicode points to glyphs. They need
|
||||
* to be sorted, because vtfont_lookup() performs a binary search. Each
|
||||
* font has two remapping tables, for normal and bold. When a character
|
||||
* is not present in bold, it uses a normal glyph. When no glyph is
|
||||
* available, it uses glyph 0, which is normally equal to U+FFFD.
|
||||
*/
|
||||
|
||||
struct vt_font_map {
|
||||
uint32_t vfm_src;
|
||||
uint16_t vfm_dst;
|
||||
uint16_t vfm_len;
|
||||
};
|
||||
|
||||
struct vt_font {
|
||||
struct vt_font_map *vf_bold;
|
||||
struct vt_font_map *vf_normal;
|
||||
uint8_t *vf_bytes;
|
||||
unsigned int vf_height, vf_width,
|
||||
vf_normal_length, vf_bold_length;
|
||||
unsigned int vf_refcount;
|
||||
};
|
||||
|
||||
struct mouse_cursor {
|
||||
uint8_t map[64 * 64 / 8];
|
||||
uint8_t mask[64 * 64 / 8];
|
||||
uint8_t w;
|
||||
uint8_t h;
|
||||
};
|
||||
|
||||
const uint8_t *vtfont_lookup(const struct vt_font *vf, term_char_t c);
|
||||
struct vt_font *vtfont_ref(struct vt_font *vf);
|
||||
void vtfont_unref(struct vt_font *vf);
|
||||
int vtfont_load(vfnt_t *f, struct vt_font **ret);
|
||||
|
||||
/* Sysmouse. */
|
||||
void sysmouse_process_event(mouse_info_t *mi);
|
||||
void vt_mouse_event(int type, int x, int y, int event, int cnt);
|
||||
void vt_mouse_state(int show);
|
||||
#define VT_MOUSE_SHOW 1
|
||||
#define VT_MOUSE_HIDE 0
|
||||
|
||||
#endif /* !_DEV_VT_VT_H_ */
|
||||
|
730
sys/dev/vt/vt_buf.c
Normal file
730
sys/dev/vt/vt_buf.c
Normal file
@ -0,0 +1,730 @@
|
||||
/*-
|
||||
* Copyright (c) 2009, 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Ed Schouten under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Portions of this software were developed by Oleksandr Rybalko
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
|
||||
static MALLOC_DEFINE(M_VTBUF, "vtbuf", "vt buffer");
|
||||
|
||||
#define VTBUF_LOCK(vb) mtx_lock_spin(&(vb)->vb_lock)
|
||||
#define VTBUF_UNLOCK(vb) mtx_unlock_spin(&(vb)->vb_lock)
|
||||
|
||||
#define POS_INDEX(c, r) (((r) << 12) + (c))
|
||||
#define POS_COPY(d, s) do { \
|
||||
(d).tp_col = (s).tp_col; \
|
||||
(d).tp_row = (s).tp_row; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* line4
|
||||
* line5 <--- curroffset (terminal output to that line)
|
||||
* line0
|
||||
* line1 <--- roffset (history display from that point)
|
||||
* line2
|
||||
* line3
|
||||
*/
|
||||
int
|
||||
vthistory_seek(struct vt_buf *vb, int offset, int whence)
|
||||
{
|
||||
int diff, top, bottom, roffset;
|
||||
|
||||
/* No scrolling if not enabled. */
|
||||
if ((vb->vb_flags & VBF_SCROLL) == 0) {
|
||||
if (vb->vb_roffset != vb->vb_curroffset) {
|
||||
vb->vb_roffset = vb->vb_curroffset;
|
||||
return (0xffff);
|
||||
}
|
||||
return (0); /* No changes */
|
||||
}
|
||||
top = (vb->vb_flags & VBF_HISTORY_FULL)?
|
||||
(vb->vb_curroffset + vb->vb_scr_size.tp_row):vb->vb_history_size;
|
||||
bottom = vb->vb_curroffset + vb->vb_history_size;
|
||||
|
||||
/*
|
||||
* Operate on copy of offset value, since it temporary can be bigger
|
||||
* than amount of rows in buffer.
|
||||
*/
|
||||
roffset = vb->vb_roffset + vb->vb_history_size;
|
||||
switch (whence) {
|
||||
case VHS_SET:
|
||||
roffset = offset + vb->vb_history_size;
|
||||
break;
|
||||
case VHS_CUR:
|
||||
roffset += offset;
|
||||
break;
|
||||
case VHS_END:
|
||||
/* Go to current offset. */
|
||||
roffset = vb->vb_curroffset + vb->vb_history_size;
|
||||
break;
|
||||
}
|
||||
|
||||
roffset = (roffset < top)?top:roffset;
|
||||
roffset = (roffset > bottom)?bottom:roffset;
|
||||
|
||||
roffset %= vb->vb_history_size;
|
||||
|
||||
if (vb->vb_roffset != roffset) {
|
||||
diff = vb->vb_roffset - roffset;
|
||||
vb->vb_roffset = roffset;
|
||||
/*
|
||||
* Offset changed, please update Nth lines on sceen.
|
||||
* +N - Nth lines at top;
|
||||
* -N - Nth lines at bottom.
|
||||
*/
|
||||
return (diff);
|
||||
}
|
||||
return (0); /* No changes */
|
||||
}
|
||||
|
||||
void
|
||||
vthistory_addlines(struct vt_buf *vb, int offset)
|
||||
{
|
||||
|
||||
vb->vb_curroffset += offset;
|
||||
if (vb->vb_curroffset < 0)
|
||||
vb->vb_curroffset = 0;
|
||||
vb->vb_curroffset %= vb->vb_history_size;
|
||||
if ((vb->vb_flags & VBF_SCROLL) == 0) {
|
||||
vb->vb_roffset = vb->vb_curroffset;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vthistory_getpos(const struct vt_buf *vb, unsigned int *offset)
|
||||
{
|
||||
|
||||
*offset = vb->vb_roffset;
|
||||
}
|
||||
|
||||
/* Translate current view row number to history row. */
|
||||
static int
|
||||
vtbuf_wth(struct vt_buf *vb, int row)
|
||||
{
|
||||
|
||||
return ((vb->vb_roffset + row) % vb->vb_history_size);
|
||||
}
|
||||
|
||||
/* Translate history row to current view row number. */
|
||||
static int
|
||||
vtbuf_htw(struct vt_buf *vb, int row)
|
||||
{
|
||||
|
||||
/*
|
||||
* total 1000 rows.
|
||||
* History offset roffset winrow
|
||||
* 205 200 ((205 - 200 + 1000) % 1000) = 5
|
||||
* 90 990 ((90 - 990 + 1000) % 1000) = 100
|
||||
*/
|
||||
return ((row - vb->vb_roffset + vb->vb_history_size) %
|
||||
vb->vb_history_size);
|
||||
}
|
||||
|
||||
int
|
||||
vtbuf_iscursor(struct vt_buf *vb, int row, int col)
|
||||
{
|
||||
int sc, sr, ec, er, tmp;
|
||||
|
||||
if ((vb->vb_flags & (VBF_CURSOR|VBF_SCROLL)) == VBF_CURSOR &&
|
||||
(vb->vb_cursor.tp_row == row) && (vb->vb_cursor.tp_col == col))
|
||||
return (1);
|
||||
|
||||
/* Mark cut/paste region. */
|
||||
|
||||
/*
|
||||
* Luckily screen view is not like circular buffer, so we will
|
||||
* calculate in screen coordinates. Translate first.
|
||||
*/
|
||||
sc = vb->vb_mark_start.tp_col;
|
||||
sr = vtbuf_htw(vb, vb->vb_mark_start.tp_row);
|
||||
ec = vb->vb_mark_end.tp_col;
|
||||
er = vtbuf_htw(vb, vb->vb_mark_end.tp_row);
|
||||
|
||||
|
||||
/* Swap start and end if start > end. */
|
||||
if (POS_INDEX(sc, sr) > POS_INDEX(ec, er)) {
|
||||
tmp = sc; sc = ec; ec = tmp;
|
||||
tmp = sr; sr = er; er = tmp;
|
||||
}
|
||||
|
||||
if ((POS_INDEX(sc, sr) <= POS_INDEX(col, row)) &&
|
||||
(POS_INDEX(col, row) < POS_INDEX(ec, er)))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
vtbuf_dirty_axis(unsigned int begin, unsigned int end)
|
||||
{
|
||||
uint64_t left, right, mask;
|
||||
|
||||
/*
|
||||
* Mark all bits between begin % 64 and end % 64 dirty.
|
||||
* This code is functionally equivalent to:
|
||||
*
|
||||
* for (i = begin; i < end; i++)
|
||||
* mask |= (uint64_t)1 << (i % 64);
|
||||
*/
|
||||
|
||||
/* Obvious case. Mark everything dirty. */
|
||||
if (end - begin >= 64)
|
||||
return (VBM_DIRTY);
|
||||
|
||||
/* 1....0; used bits on the left. */
|
||||
left = VBM_DIRTY << begin % 64;
|
||||
/* 0....1; used bits on the right. */
|
||||
right = VBM_DIRTY >> -end % 64;
|
||||
|
||||
/*
|
||||
* Only take the intersection. If the result of that is 0, it
|
||||
* means that the selection crossed a 64 bit boundary along the
|
||||
* way, which means we have to take the complement.
|
||||
*/
|
||||
mask = left & right;
|
||||
if (mask == 0)
|
||||
mask = left | right;
|
||||
return (mask);
|
||||
}
|
||||
|
||||
static inline void
|
||||
vtbuf_dirty(struct vt_buf *vb, const term_rect_t *area)
|
||||
{
|
||||
|
||||
VTBUF_LOCK(vb);
|
||||
if (vb->vb_dirtyrect.tr_begin.tp_row > area->tr_begin.tp_row)
|
||||
vb->vb_dirtyrect.tr_begin.tp_row = area->tr_begin.tp_row;
|
||||
if (vb->vb_dirtyrect.tr_begin.tp_col > area->tr_begin.tp_col)
|
||||
vb->vb_dirtyrect.tr_begin.tp_col = area->tr_begin.tp_col;
|
||||
if (vb->vb_dirtyrect.tr_end.tp_row < area->tr_end.tp_row)
|
||||
vb->vb_dirtyrect.tr_end.tp_row = area->tr_end.tp_row;
|
||||
if (vb->vb_dirtyrect.tr_end.tp_col < area->tr_end.tp_col)
|
||||
vb->vb_dirtyrect.tr_end.tp_col = area->tr_end.tp_col;
|
||||
vb->vb_dirtymask.vbm_row |=
|
||||
vtbuf_dirty_axis(area->tr_begin.tp_row, area->tr_end.tp_row);
|
||||
vb->vb_dirtymask.vbm_col |=
|
||||
vtbuf_dirty_axis(area->tr_begin.tp_col, area->tr_end.tp_col);
|
||||
VTBUF_UNLOCK(vb);
|
||||
}
|
||||
|
||||
static inline void
|
||||
vtbuf_dirty_cell(struct vt_buf *vb, const term_pos_t *p)
|
||||
{
|
||||
term_rect_t area;
|
||||
|
||||
area.tr_begin = *p;
|
||||
area.tr_end.tp_row = p->tp_row + 1;
|
||||
area.tr_end.tp_col = p->tp_col + 1;
|
||||
vtbuf_dirty(vb, &area);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbuf_make_undirty(struct vt_buf *vb)
|
||||
{
|
||||
|
||||
vb->vb_dirtyrect.tr_begin = vb->vb_scr_size;
|
||||
vb->vb_dirtyrect.tr_end.tp_row = vb->vb_dirtyrect.tr_end.tp_col = 0;
|
||||
vb->vb_dirtymask.vbm_row = vb->vb_dirtymask.vbm_col = 0;
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_undirty(struct vt_buf *vb, term_rect_t *r, struct vt_bufmask *m)
|
||||
{
|
||||
|
||||
VTBUF_LOCK(vb);
|
||||
*r = vb->vb_dirtyrect;
|
||||
*m = vb->vb_dirtymask;
|
||||
vtbuf_make_undirty(vb);
|
||||
VTBUF_UNLOCK(vb);
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_copy(struct vt_buf *vb, const term_rect_t *r, const term_pos_t *p2)
|
||||
{
|
||||
const term_pos_t *p1 = &r->tr_begin;
|
||||
term_rect_t area;
|
||||
unsigned int rows, cols;
|
||||
int pr, rdiff;
|
||||
|
||||
KASSERT(r->tr_begin.tp_row < vb->vb_scr_size.tp_row,
|
||||
("vtbuf_copy begin.tp_row %d must be less than screen width %d",
|
||||
r->tr_begin.tp_row, vb->vb_scr_size.tp_row));
|
||||
KASSERT(r->tr_begin.tp_col < vb->vb_scr_size.tp_col,
|
||||
("vtbuf_copy begin.tp_col %d must be less than screen height %d",
|
||||
r->tr_begin.tp_col, vb->vb_scr_size.tp_col));
|
||||
|
||||
KASSERT(r->tr_end.tp_row <= vb->vb_scr_size.tp_row,
|
||||
("vtbuf_copy end.tp_row %d must be less than screen width %d",
|
||||
r->tr_end.tp_row, vb->vb_scr_size.tp_row));
|
||||
KASSERT(r->tr_end.tp_col <= vb->vb_scr_size.tp_col,
|
||||
("vtbuf_copy end.tp_col %d must be less than screen height %d",
|
||||
r->tr_end.tp_col, vb->vb_scr_size.tp_col));
|
||||
|
||||
KASSERT(p2->tp_row < vb->vb_scr_size.tp_row,
|
||||
("vtbuf_copy tp_row %d must be less than screen width %d",
|
||||
p2->tp_row, vb->vb_scr_size.tp_row));
|
||||
KASSERT(p2->tp_col < vb->vb_scr_size.tp_col,
|
||||
("vtbuf_copy tp_col %d must be less than screen height %d",
|
||||
p2->tp_col, vb->vb_scr_size.tp_col));
|
||||
|
||||
rows = r->tr_end.tp_row - r->tr_begin.tp_row;
|
||||
rdiff = r->tr_begin.tp_row - p2->tp_row;
|
||||
cols = r->tr_end.tp_col - r->tr_begin.tp_col;
|
||||
if (r->tr_begin.tp_row > p2->tp_row && r->tr_begin.tp_col == 0 &&
|
||||
r->tr_end.tp_col == vb->vb_scr_size.tp_col && /* Full row. */
|
||||
(rows + rdiff) == vb->vb_scr_size.tp_row && /* Whole screen. */
|
||||
rdiff > 0) { /* Only forward dirrection. Do not eat history. */
|
||||
vthistory_addlines(vb, rdiff);
|
||||
} else if (p2->tp_row < p1->tp_row) {
|
||||
/* Handle overlapping copies of line segments. */
|
||||
/* Move data up. */
|
||||
for (pr = 0; pr < rows; pr++)
|
||||
memmove(
|
||||
&VTBUF_FIELD(vb, p2->tp_row + pr, p2->tp_col),
|
||||
&VTBUF_FIELD(vb, p1->tp_row + pr, p1->tp_col),
|
||||
cols * sizeof(term_char_t));
|
||||
} else {
|
||||
/* Move data down. */
|
||||
for (pr = rows - 1; pr >= 0; pr--)
|
||||
memmove(
|
||||
&VTBUF_FIELD(vb, p2->tp_row + pr, p2->tp_col),
|
||||
&VTBUF_FIELD(vb, p1->tp_row + pr, p1->tp_col),
|
||||
cols * sizeof(term_char_t));
|
||||
}
|
||||
|
||||
area.tr_begin = *p2;
|
||||
area.tr_end.tp_row = MIN(p2->tp_row + rows, vb->vb_scr_size.tp_row);
|
||||
area.tr_end.tp_col = MIN(p2->tp_col + cols, vb->vb_scr_size.tp_col);
|
||||
vtbuf_dirty(vb, &area);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbuf_fill(struct vt_buf *vb, const term_rect_t *r, term_char_t c)
|
||||
{
|
||||
unsigned int pr, pc;
|
||||
term_char_t *row;
|
||||
|
||||
for (pr = r->tr_begin.tp_row; pr < r->tr_end.tp_row; pr++) {
|
||||
row = vb->vb_rows[(vb->vb_curroffset + pr) %
|
||||
VTBUF_MAX_HEIGHT(vb)];
|
||||
for (pc = r->tr_begin.tp_col; pc < r->tr_end.tp_col; pc++) {
|
||||
row[pc] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_fill_locked(struct vt_buf *vb, const term_rect_t *r, term_char_t c)
|
||||
{
|
||||
KASSERT(r->tr_begin.tp_row < vb->vb_scr_size.tp_row,
|
||||
("vtbuf_fill_locked begin.tp_row %d must be < screen width %d",
|
||||
r->tr_begin.tp_row, vb->vb_scr_size.tp_row));
|
||||
KASSERT(r->tr_begin.tp_col < vb->vb_scr_size.tp_col,
|
||||
("vtbuf_fill_locked begin.tp_col %d must be < screen height %d",
|
||||
r->tr_begin.tp_col, vb->vb_scr_size.tp_col));
|
||||
|
||||
KASSERT(r->tr_end.tp_row <= vb->vb_scr_size.tp_row,
|
||||
("vtbuf_fill_locked end.tp_row %d must be <= screen width %d",
|
||||
r->tr_end.tp_row, vb->vb_scr_size.tp_row));
|
||||
KASSERT(r->tr_end.tp_col <= vb->vb_scr_size.tp_col,
|
||||
("vtbuf_fill_locked end.tp_col %d must be <= screen height %d",
|
||||
r->tr_end.tp_col, vb->vb_scr_size.tp_col));
|
||||
|
||||
VTBUF_LOCK(vb);
|
||||
vtbuf_fill(vb, r, c);
|
||||
VTBUF_UNLOCK(vb);
|
||||
|
||||
vtbuf_dirty(vb, r);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbuf_init_rows(struct vt_buf *vb)
|
||||
{
|
||||
int r;
|
||||
|
||||
vb->vb_history_size = MAX(vb->vb_history_size, vb->vb_scr_size.tp_row);
|
||||
|
||||
for (r = 0; r < vb->vb_history_size; r++)
|
||||
vb->vb_rows[r] = &vb->vb_buffer[r *
|
||||
vb->vb_scr_size.tp_col];
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_init_early(struct vt_buf *vb)
|
||||
{
|
||||
|
||||
vb->vb_flags |= VBF_CURSOR;
|
||||
vb->vb_roffset = 0;
|
||||
vb->vb_curroffset = 0;
|
||||
vb->vb_mark_start.tp_row = 0;
|
||||
vb->vb_mark_start.tp_col = 0;
|
||||
vb->vb_mark_end.tp_row = 0;
|
||||
vb->vb_mark_end.tp_col = 0;
|
||||
|
||||
vtbuf_init_rows(vb);
|
||||
vtbuf_make_undirty(vb);
|
||||
if ((vb->vb_flags & VBF_MTX_INIT) == 0) {
|
||||
mtx_init(&vb->vb_lock, "vtbuf", NULL, MTX_SPIN);
|
||||
vb->vb_flags |= VBF_MTX_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_init(struct vt_buf *vb, const term_pos_t *p)
|
||||
{
|
||||
int sz;
|
||||
|
||||
vb->vb_scr_size = *p;
|
||||
vb->vb_history_size = VBF_DEFAULT_HISTORY_SIZE;
|
||||
|
||||
if ((vb->vb_flags & VBF_STATIC) == 0) {
|
||||
sz = vb->vb_history_size * p->tp_col * sizeof(term_char_t);
|
||||
vb->vb_buffer = malloc(sz, M_VTBUF, M_WAITOK | M_ZERO);
|
||||
|
||||
sz = vb->vb_history_size * sizeof(term_char_t *);
|
||||
vb->vb_rows = malloc(sz, M_VTBUF, M_WAITOK | M_ZERO);
|
||||
}
|
||||
|
||||
vtbuf_init_early(vb);
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_sethistory_size(struct vt_buf *vb, int size)
|
||||
{
|
||||
term_pos_t p;
|
||||
|
||||
/* With same size */
|
||||
p.tp_row = vb->vb_scr_size.tp_row;
|
||||
p.tp_col = vb->vb_scr_size.tp_col;
|
||||
vtbuf_grow(vb, &p, size);
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_grow(struct vt_buf *vb, const term_pos_t *p, int history_size)
|
||||
{
|
||||
term_char_t *old, *new, **rows, **oldrows, **copyrows, *row;
|
||||
int bufsize, rowssize, w, h, c, r;
|
||||
term_rect_t rect;
|
||||
|
||||
history_size = MAX(history_size, p->tp_row);
|
||||
|
||||
if (history_size > vb->vb_history_size || p->tp_col >
|
||||
vb->vb_scr_size.tp_col) {
|
||||
/* Allocate new buffer. */
|
||||
bufsize = history_size * p->tp_col * sizeof(term_char_t);
|
||||
new = malloc(bufsize, M_VTBUF, M_WAITOK | M_ZERO);
|
||||
rowssize = history_size * sizeof(term_pos_t *);
|
||||
rows = malloc(rowssize, M_VTBUF, M_WAITOK | M_ZERO);
|
||||
|
||||
/* Toggle it. */
|
||||
VTBUF_LOCK(vb);
|
||||
old = vb->vb_flags & VBF_STATIC ? NULL : vb->vb_buffer;
|
||||
oldrows = vb->vb_flags & VBF_STATIC ? NULL : vb->vb_rows;
|
||||
copyrows = vb->vb_rows;
|
||||
w = vb->vb_scr_size.tp_col;
|
||||
h = vb->vb_history_size;
|
||||
|
||||
vb->vb_history_size = history_size;
|
||||
vb->vb_buffer = new;
|
||||
vb->vb_rows = rows;
|
||||
vb->vb_flags &= ~VBF_STATIC;
|
||||
vb->vb_scr_size = *p;
|
||||
vtbuf_init_rows(vb);
|
||||
|
||||
/* Copy history and fill extra space. */
|
||||
for (r = 0; r < history_size; r ++) {
|
||||
row = rows[r];
|
||||
if (r < h) { /* Copy. */
|
||||
memmove(rows[r], copyrows[r],
|
||||
MIN(p->tp_col, w) * sizeof(term_char_t));
|
||||
for (c = MIN(p->tp_col, w); c < p->tp_col;
|
||||
c++) {
|
||||
row[c] = VTBUF_SPACE_CHAR;
|
||||
}
|
||||
} else { /* Just fill. */
|
||||
rect.tr_begin.tp_col = 0;
|
||||
rect.tr_begin.tp_row = r;
|
||||
rect.tr_end.tp_col = p->tp_col;
|
||||
rect.tr_end.tp_row = p->tp_row;
|
||||
vtbuf_fill(vb, &rect, VTBUF_SPACE_CHAR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
vtbuf_make_undirty(vb);
|
||||
VTBUF_UNLOCK(vb);
|
||||
/* Deallocate old buffer. */
|
||||
free(old, M_VTBUF);
|
||||
free(oldrows, M_VTBUF);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_putchar(struct vt_buf *vb, const term_pos_t *p, term_char_t c)
|
||||
{
|
||||
term_char_t *row;
|
||||
|
||||
KASSERT(p->tp_row < vb->vb_scr_size.tp_row,
|
||||
("vtbuf_putchar tp_row %d must be less than screen width %d",
|
||||
p->tp_row, vb->vb_scr_size.tp_row));
|
||||
KASSERT(p->tp_col < vb->vb_scr_size.tp_col,
|
||||
("vtbuf_putchar tp_col %d must be less than screen height %d",
|
||||
p->tp_col, vb->vb_scr_size.tp_col));
|
||||
|
||||
row = vb->vb_rows[(vb->vb_curroffset + p->tp_row) %
|
||||
VTBUF_MAX_HEIGHT(vb)];
|
||||
if (row[p->tp_col] != c) {
|
||||
VTBUF_LOCK(vb);
|
||||
row[p->tp_col] = c;
|
||||
VTBUF_UNLOCK(vb);
|
||||
vtbuf_dirty_cell(vb, p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_cursor_position(struct vt_buf *vb, const term_pos_t *p)
|
||||
{
|
||||
|
||||
if (vb->vb_flags & VBF_CURSOR) {
|
||||
vtbuf_dirty_cell(vb, &vb->vb_cursor);
|
||||
vb->vb_cursor = *p;
|
||||
vtbuf_dirty_cell(vb, &vb->vb_cursor);
|
||||
} else {
|
||||
vb->vb_cursor = *p;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_mouse_cursor_position(struct vt_buf *vb, int col, int row)
|
||||
{
|
||||
term_rect_t area;
|
||||
|
||||
area.tr_begin.tp_row = MAX(row - 1, 0);
|
||||
area.tr_begin.tp_col = MAX(col - 1, 0);
|
||||
area.tr_end.tp_row = MIN(row + 2, vb->vb_scr_size.tp_row);
|
||||
area.tr_end.tp_col = MIN(col + 2, vb->vb_scr_size.tp_col);
|
||||
vtbuf_dirty(vb, &area);
|
||||
}
|
||||
|
||||
static void
|
||||
vtbuf_flush_mark(struct vt_buf *vb)
|
||||
{
|
||||
term_rect_t area;
|
||||
int s, e;
|
||||
|
||||
/* Notify renderer to update marked region. */
|
||||
if (vb->vb_mark_start.tp_col || vb->vb_mark_end.tp_col ||
|
||||
vb->vb_mark_start.tp_row || vb->vb_mark_end.tp_row) {
|
||||
|
||||
s = vtbuf_htw(vb, vb->vb_mark_start.tp_row);
|
||||
e = vtbuf_htw(vb, vb->vb_mark_end.tp_row);
|
||||
|
||||
area.tr_begin.tp_col = 0;
|
||||
area.tr_begin.tp_row = MIN(s, e);
|
||||
|
||||
area.tr_end.tp_col = vb->vb_scr_size.tp_col;
|
||||
area.tr_end.tp_row = MAX(s, e) + 1;
|
||||
|
||||
vtbuf_dirty(vb, &area);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
vtbuf_get_marked_len(struct vt_buf *vb)
|
||||
{
|
||||
int ei, si, sz;
|
||||
term_pos_t s, e;
|
||||
|
||||
/* Swap according to window coordinates. */
|
||||
if (POS_INDEX(vtbuf_htw(vb, vb->vb_mark_start.tp_row),
|
||||
vb->vb_mark_start.tp_col) >
|
||||
POS_INDEX(vtbuf_htw(vb, vb->vb_mark_end.tp_row),
|
||||
vb->vb_mark_end.tp_col)) {
|
||||
POS_COPY(e, vb->vb_mark_start);
|
||||
POS_COPY(s, vb->vb_mark_end);
|
||||
} else {
|
||||
POS_COPY(s, vb->vb_mark_start);
|
||||
POS_COPY(e, vb->vb_mark_end);
|
||||
}
|
||||
|
||||
si = s.tp_row * vb->vb_scr_size.tp_col + s.tp_col;
|
||||
ei = e.tp_row * vb->vb_scr_size.tp_col + e.tp_col;
|
||||
|
||||
/* Number symbols and number of rows to inject \n */
|
||||
sz = ei - si + ((e.tp_row - s.tp_row) * 2) + 1;
|
||||
|
||||
return (sz * sizeof(term_char_t));
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_extract_marked(struct vt_buf *vb, term_char_t *buf, int sz)
|
||||
{
|
||||
int i, r, c, cs, ce;
|
||||
term_pos_t s, e;
|
||||
|
||||
/* Swap according to window coordinates. */
|
||||
if (POS_INDEX(vtbuf_htw(vb, vb->vb_mark_start.tp_row),
|
||||
vb->vb_mark_start.tp_col) >
|
||||
POS_INDEX(vtbuf_htw(vb, vb->vb_mark_end.tp_row),
|
||||
vb->vb_mark_end.tp_col)) {
|
||||
POS_COPY(e, vb->vb_mark_start);
|
||||
POS_COPY(s, vb->vb_mark_end);
|
||||
} else {
|
||||
POS_COPY(s, vb->vb_mark_start);
|
||||
POS_COPY(e, vb->vb_mark_end);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (r = s.tp_row; r <= e.tp_row; r ++) {
|
||||
cs = (r == s.tp_row)?s.tp_col:0;
|
||||
ce = (r == e.tp_row)?e.tp_col:vb->vb_scr_size.tp_col;
|
||||
for (c = cs; c < ce; c ++) {
|
||||
buf[i++] = vb->vb_rows[r][c];
|
||||
}
|
||||
/* Add new line for all rows, but not for last one. */
|
||||
if (r != e.tp_row) {
|
||||
buf[i++] = '\r';
|
||||
buf[i++] = '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
vtbuf_set_mark(struct vt_buf *vb, int type, int col, int row)
|
||||
{
|
||||
term_char_t *r;
|
||||
int i;
|
||||
|
||||
switch (type) {
|
||||
case VTB_MARK_END: /* B1 UP */
|
||||
if (vb->vb_mark_last != VTB_MARK_MOVE)
|
||||
return (0);
|
||||
/* FALLTHROUGH */
|
||||
case VTB_MARK_MOVE:
|
||||
case VTB_MARK_EXTEND:
|
||||
vtbuf_flush_mark(vb); /* Clean old mark. */
|
||||
vb->vb_mark_end.tp_col = col;
|
||||
vb->vb_mark_end.tp_row = vtbuf_wth(vb, row);
|
||||
break;
|
||||
case VTB_MARK_START:
|
||||
vtbuf_flush_mark(vb); /* Clean old mark. */
|
||||
vb->vb_mark_start.tp_col = col;
|
||||
vb->vb_mark_start.tp_row = vtbuf_wth(vb, row);
|
||||
/* Start again, so clear end point. */
|
||||
vb->vb_mark_end.tp_col = col;
|
||||
vb->vb_mark_end.tp_row = vtbuf_wth(vb, row);
|
||||
break;
|
||||
case VTB_MARK_WORD:
|
||||
vtbuf_flush_mark(vb); /* Clean old mark. */
|
||||
vb->vb_mark_start.tp_row = vb->vb_mark_end.tp_row =
|
||||
vtbuf_wth(vb, row);
|
||||
r = vb->vb_rows[vb->vb_mark_start.tp_row];
|
||||
for (i = col; i >= 0; i --) {
|
||||
if (TCHAR_CHARACTER(r[i]) == ' ') {
|
||||
vb->vb_mark_start.tp_col = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = col; i < vb->vb_scr_size.tp_col; i ++) {
|
||||
if (TCHAR_CHARACTER(r[i]) == ' ') {
|
||||
vb->vb_mark_end.tp_col = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vb->vb_mark_start.tp_col > vb->vb_mark_end.tp_col)
|
||||
vb->vb_mark_start.tp_col = vb->vb_mark_end.tp_col;
|
||||
break;
|
||||
case VTB_MARK_ROW:
|
||||
vtbuf_flush_mark(vb); /* Clean old mark. */
|
||||
vb->vb_mark_start.tp_col = 0;
|
||||
vb->vb_mark_end.tp_col = vb->vb_scr_size.tp_col;
|
||||
vb->vb_mark_start.tp_row = vb->vb_mark_end.tp_row =
|
||||
vtbuf_wth(vb, row);
|
||||
break;
|
||||
case VTB_MARK_NONE:
|
||||
vb->vb_mark_last = type;
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
/* panic? */
|
||||
return (0);
|
||||
}
|
||||
|
||||
vb->vb_mark_last = type;
|
||||
/* Draw new marked region. */
|
||||
vtbuf_flush_mark(vb);
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_cursor_visibility(struct vt_buf *vb, int yes)
|
||||
{
|
||||
int oflags, nflags;
|
||||
|
||||
VTBUF_LOCK(vb);
|
||||
oflags = vb->vb_flags;
|
||||
if (yes)
|
||||
vb->vb_flags |= VBF_CURSOR;
|
||||
else
|
||||
vb->vb_flags &= ~VBF_CURSOR;
|
||||
nflags = vb->vb_flags;
|
||||
VTBUF_UNLOCK(vb);
|
||||
|
||||
if (oflags != nflags)
|
||||
vtbuf_dirty_cell(vb, &vb->vb_cursor);
|
||||
}
|
||||
|
||||
void
|
||||
vtbuf_scroll_mode(struct vt_buf *vb, int yes)
|
||||
{
|
||||
int oflags, nflags;
|
||||
|
||||
VTBUF_LOCK(vb);
|
||||
oflags = vb->vb_flags;
|
||||
if (yes)
|
||||
vb->vb_flags |= VBF_SCROLL;
|
||||
else
|
||||
vb->vb_flags &= ~VBF_SCROLL;
|
||||
nflags = vb->vb_flags;
|
||||
VTBUF_UNLOCK(vb);
|
||||
|
||||
if (oflags != nflags)
|
||||
vtbuf_dirty_cell(vb, &vb->vb_cursor);
|
||||
}
|
||||
|
79
sys/dev/vt/vt_consolectl.c
Normal file
79
sys/dev/vt/vt_consolectl.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Ed Schouten under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
|
||||
static d_ioctl_t consolectl_ioctl;
|
||||
|
||||
static struct cdevsw consolectl_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_ioctl = consolectl_ioctl,
|
||||
.d_name = "consolectl",
|
||||
};
|
||||
|
||||
static int
|
||||
consolectl_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
||||
struct thread *td)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
case CONS_GETVERS:
|
||||
*(int*)data = 0x200;
|
||||
return 0;
|
||||
case CONS_MOUSECTL: {
|
||||
mouse_info_t *mi = (mouse_info_t*)data;
|
||||
|
||||
sysmouse_process_event(mi);
|
||||
return (0);
|
||||
}
|
||||
default:
|
||||
printf("consolectl: unknown ioctl: %c:%lx\n",
|
||||
(char)IOCGROUP(cmd), IOCBASECMD(cmd));
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
consolectl_drvinit(void *unused)
|
||||
{
|
||||
|
||||
make_dev(&consolectl_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
|
||||
"consolectl");
|
||||
}
|
||||
|
||||
SYSINIT(consolectl, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, consolectl_drvinit, NULL);
|
1822
sys/dev/vt/vt_core.c
Normal file
1822
sys/dev/vt/vt_core.c
Normal file
File diff suppressed because it is too large
Load Diff
212
sys/dev/vt/vt_font.c
Normal file
212
sys/dev/vt/vt_font.c
Normal file
@ -0,0 +1,212 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Ed Schouten under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/refcount.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
|
||||
static MALLOC_DEFINE(M_VTFONT, "vtfont", "vt font");
|
||||
|
||||
/* Some limits to prevent abnormal fonts from being loaded. */
|
||||
#define VTFONT_MAXMAPPINGS 1024
|
||||
#define VTFONT_MAXGLYPHSIZE 262144
|
||||
#define VTFONT_MAXDIMENSION 128
|
||||
|
||||
static uint16_t
|
||||
vtfont_bisearch(const struct vt_font_map *map, unsigned int len, uint32_t src)
|
||||
{
|
||||
int min, mid, max;
|
||||
|
||||
min = 0;
|
||||
max = len - 1;
|
||||
|
||||
/* Empty font map. */
|
||||
if (len == 0)
|
||||
return (0);
|
||||
/* Character below minimal entry. */
|
||||
if (src < map[0].vfm_src)
|
||||
return (0);
|
||||
/* Optimization: ASCII characters occur very often. */
|
||||
if (src <= map[0].vfm_src + map[0].vfm_len)
|
||||
return (src - map[0].vfm_src + map[0].vfm_dst);
|
||||
/* Character above maximum entry. */
|
||||
if (src > map[max].vfm_src + map[max].vfm_len)
|
||||
return (0);
|
||||
|
||||
/* Binary search. */
|
||||
while (max >= min) {
|
||||
mid = (min + max) / 2;
|
||||
if (src < map[mid].vfm_src)
|
||||
max = mid - 1;
|
||||
else if (src > map[mid].vfm_src + map[mid].vfm_len)
|
||||
min = mid + 1;
|
||||
else
|
||||
return (src - map[mid].vfm_src + map[mid].vfm_dst);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
const uint8_t *
|
||||
vtfont_lookup(const struct vt_font *vf, term_char_t c)
|
||||
{
|
||||
uint32_t src;
|
||||
uint16_t dst;
|
||||
size_t stride;
|
||||
|
||||
src = TCHAR_CHARACTER(c);
|
||||
if (TCHAR_FORMAT(c) & TF_BOLD) {
|
||||
dst = vtfont_bisearch(vf->vf_bold, vf->vf_bold_length, src);
|
||||
if (dst != 0)
|
||||
goto found;
|
||||
}
|
||||
dst = vtfont_bisearch(vf->vf_normal, vf->vf_normal_length, src);
|
||||
|
||||
found:
|
||||
stride = howmany(vf->vf_width, 8) * vf->vf_height;
|
||||
return (&vf->vf_bytes[dst * stride]);
|
||||
}
|
||||
|
||||
struct vt_font *
|
||||
vtfont_ref(struct vt_font *vf)
|
||||
{
|
||||
|
||||
refcount_acquire(&vf->vf_refcount);
|
||||
return (vf);
|
||||
}
|
||||
|
||||
void
|
||||
vtfont_unref(struct vt_font *vf)
|
||||
{
|
||||
|
||||
if (refcount_release(&vf->vf_refcount)) {
|
||||
free(vf->vf_normal, M_VTFONT);
|
||||
free(vf->vf_bold, M_VTFONT);
|
||||
free(vf->vf_bytes, M_VTFONT);
|
||||
free(vf, M_VTFONT);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vtfont_validate_map(struct vt_font_map *vfm, unsigned int length,
|
||||
unsigned int nglyphs)
|
||||
{
|
||||
unsigned int i, last = 0;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
/* Not ordered. */
|
||||
if (i > 0 && vfm[i].vfm_src <= last)
|
||||
return (EINVAL);
|
||||
/*
|
||||
* Destination extends amount of glyphs.
|
||||
*/
|
||||
if (vfm[i].vfm_dst >= nglyphs ||
|
||||
vfm[i].vfm_dst + vfm[i].vfm_len >= nglyphs)
|
||||
return (EINVAL);
|
||||
last = vfm[i].vfm_src + vfm[i].vfm_len;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
vtfont_load(vfnt_t *f, struct vt_font **ret)
|
||||
{
|
||||
size_t glyphsize;
|
||||
struct vt_font *vf;
|
||||
int error;
|
||||
|
||||
/* Make sure the dimensions are valid. */
|
||||
if (f->width < 1 || f->height < 1)
|
||||
return (EINVAL);
|
||||
if (f->width > VTFONT_MAXDIMENSION || f->height > VTFONT_MAXDIMENSION)
|
||||
return (E2BIG);
|
||||
|
||||
/* Not too many mappings. */
|
||||
if (f->nnormal > VTFONT_MAXMAPPINGS || f->nbold > VTFONT_MAXMAPPINGS)
|
||||
return (E2BIG);
|
||||
|
||||
/* Character 0 must always be present. */
|
||||
if (f->nglyphs < 1)
|
||||
return (EINVAL);
|
||||
|
||||
glyphsize = howmany(f->width, 8) * f->height * f->nglyphs;
|
||||
if (glyphsize > VTFONT_MAXGLYPHSIZE)
|
||||
return (E2BIG);
|
||||
|
||||
/* Allocate new font structure. */
|
||||
vf = malloc(sizeof *vf, M_VTFONT, M_WAITOK);
|
||||
vf->vf_normal = malloc(f->nnormal * sizeof(struct vt_font_map),
|
||||
M_VTFONT, M_WAITOK);
|
||||
vf->vf_bold = malloc(f->nbold * sizeof(struct vt_font_map),
|
||||
M_VTFONT, M_WAITOK);
|
||||
vf->vf_bytes = malloc(glyphsize, M_VTFONT, M_WAITOK);
|
||||
vf->vf_height = f->height;
|
||||
vf->vf_width = f->width;
|
||||
vf->vf_normal_length = f->nnormal;
|
||||
vf->vf_bold_length = f->nbold;
|
||||
vf->vf_refcount = 1;
|
||||
|
||||
/* Copy in data. */
|
||||
error = copyin(f->normal, vf->vf_normal,
|
||||
vf->vf_normal_length * sizeof(struct vt_font_map));
|
||||
if (error)
|
||||
goto bad;
|
||||
error = copyin(f->bold, vf->vf_bold,
|
||||
vf->vf_bold_length * sizeof(struct vt_font_map));
|
||||
if (error)
|
||||
goto bad;
|
||||
error = copyin(f->glyphs, vf->vf_bytes, glyphsize);
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
/* Validate mappings. */
|
||||
error = vtfont_validate_map(vf->vf_normal, vf->vf_normal_length,
|
||||
f->nglyphs);
|
||||
if (error)
|
||||
goto bad;
|
||||
error = vtfont_validate_map(vf->vf_bold, vf->vf_bold_length,
|
||||
f->nglyphs);
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
/* Success. */
|
||||
*ret = vf;
|
||||
return (0);
|
||||
|
||||
bad: vtfont_unref(vf);
|
||||
return (error);
|
||||
}
|
406
sys/dev/vt/vt_sysmouse.c
Normal file
406
sys/dev/vt/vt_sysmouse.c
Normal file
@ -0,0 +1,406 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Ed Schouten under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/filio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/selinfo.h>
|
||||
#include <sys/sigio.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
|
||||
static d_open_t sysmouse_open;
|
||||
static d_close_t sysmouse_close;
|
||||
static d_read_t sysmouse_read;
|
||||
static d_ioctl_t sysmouse_ioctl;
|
||||
static d_poll_t sysmouse_poll;
|
||||
|
||||
static struct cdevsw sysmouse_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_open = sysmouse_open,
|
||||
.d_close = sysmouse_close,
|
||||
.d_read = sysmouse_read,
|
||||
.d_ioctl = sysmouse_ioctl,
|
||||
.d_poll = sysmouse_poll,
|
||||
.d_name = "sysmouse",
|
||||
};
|
||||
|
||||
static struct mtx sysmouse_lock;
|
||||
static struct cv sysmouse_sleep;
|
||||
static struct selinfo sysmouse_bufpoll;
|
||||
|
||||
static int sysmouse_level;
|
||||
static mousestatus_t sysmouse_status;
|
||||
static int sysmouse_flags;
|
||||
#define SM_ASYNC 0x1
|
||||
static struct sigio *sysmouse_sigio;
|
||||
|
||||
#define SYSMOUSE_MAXFRAMES 250 /* 2 KB */
|
||||
static MALLOC_DEFINE(M_SYSMOUSE, "sysmouse", "sysmouse device");
|
||||
static unsigned char *sysmouse_buffer;
|
||||
static unsigned int sysmouse_start, sysmouse_length;
|
||||
|
||||
static int
|
||||
sysmouse_buf_read(struct uio *uio, unsigned int length)
|
||||
{
|
||||
unsigned char buf[MOUSE_SYS_PACKETSIZE];
|
||||
int error;
|
||||
|
||||
if (sysmouse_buffer == NULL)
|
||||
return (ENXIO);
|
||||
else if (sysmouse_length == 0)
|
||||
return (EWOULDBLOCK);
|
||||
|
||||
memcpy(buf, sysmouse_buffer +
|
||||
sysmouse_start * MOUSE_SYS_PACKETSIZE, MOUSE_SYS_PACKETSIZE);
|
||||
sysmouse_start = (sysmouse_start + 1) % SYSMOUSE_MAXFRAMES;
|
||||
sysmouse_length--;
|
||||
|
||||
mtx_unlock(&sysmouse_lock);
|
||||
error = uiomove(buf, length, uio);
|
||||
mtx_lock(&sysmouse_lock);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
sysmouse_buf_store(const unsigned char buf[MOUSE_SYS_PACKETSIZE])
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
if (sysmouse_buffer == NULL || sysmouse_length == SYSMOUSE_MAXFRAMES)
|
||||
return;
|
||||
|
||||
idx = (sysmouse_start + sysmouse_length) % SYSMOUSE_MAXFRAMES;
|
||||
memcpy(sysmouse_buffer + idx * MOUSE_SYS_PACKETSIZE, buf,
|
||||
MOUSE_SYS_PACKETSIZE);
|
||||
sysmouse_length++;
|
||||
cv_broadcast(&sysmouse_sleep);
|
||||
selwakeup(&sysmouse_bufpoll);
|
||||
if (sysmouse_flags & SM_ASYNC && sysmouse_sigio != NULL)
|
||||
pgsigio(&sysmouse_sigio, SIGIO, 0);
|
||||
}
|
||||
|
||||
void
|
||||
sysmouse_process_event(mouse_info_t *mi)
|
||||
{
|
||||
/* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
|
||||
static const int buttonmap[8] = {
|
||||
MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
|
||||
MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
|
||||
MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
|
||||
MOUSE_MSC_BUTTON3UP,
|
||||
MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP,
|
||||
MOUSE_MSC_BUTTON2UP,
|
||||
MOUSE_MSC_BUTTON1UP,
|
||||
0,
|
||||
};
|
||||
unsigned char buf[MOUSE_SYS_PACKETSIZE];
|
||||
int x, y, iy, z;
|
||||
|
||||
random_harvest(mi, sizeof *mi, 2, RANDOM_MOUSE);
|
||||
|
||||
mtx_lock(&sysmouse_lock);
|
||||
switch (mi->operation) {
|
||||
case MOUSE_ACTION:
|
||||
sysmouse_status.button = mi->u.data.buttons;
|
||||
/* FALLTHROUGH */
|
||||
case MOUSE_MOTION_EVENT:
|
||||
x = mi->u.data.x;
|
||||
y = mi->u.data.y;
|
||||
z = mi->u.data.z;
|
||||
break;
|
||||
case MOUSE_BUTTON_EVENT:
|
||||
x = y = z = 0;
|
||||
if (mi->u.event.value > 0)
|
||||
sysmouse_status.button |= mi->u.event.id;
|
||||
else
|
||||
sysmouse_status.button &= ~mi->u.event.id;
|
||||
break;
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
sysmouse_status.dx += x;
|
||||
sysmouse_status.dy += y;
|
||||
sysmouse_status.dz += z;
|
||||
sysmouse_status.flags |= ((x || y || z) ? MOUSE_POSCHANGED : 0) |
|
||||
(sysmouse_status.obutton ^ sysmouse_status.button);
|
||||
if (sysmouse_status.flags == 0)
|
||||
goto done;
|
||||
|
||||
|
||||
/* The first five bytes are compatible with MouseSystems. */
|
||||
buf[0] = MOUSE_MSC_SYNC |
|
||||
buttonmap[sysmouse_status.button & MOUSE_STDBUTTONS];
|
||||
x = imax(imin(x, 255), -256);
|
||||
buf[1] = x >> 1;
|
||||
buf[3] = x - buf[1];
|
||||
iy = -imax(imin(y, 255), -256);
|
||||
buf[2] = iy >> 1;
|
||||
buf[4] = iy - buf[2];
|
||||
/* Extended part. */
|
||||
z = imax(imin(z, 127), -128);
|
||||
buf[5] = (z >> 1) & 0x7f;
|
||||
buf[6] = (z - (z >> 1)) & 0x7f;
|
||||
/* Buttons 4-10. */
|
||||
buf[7] = (~sysmouse_status.button >> 3) & 0x7f;
|
||||
|
||||
sysmouse_buf_store(buf);
|
||||
|
||||
mtx_unlock(&sysmouse_lock);
|
||||
vt_mouse_event(mi->operation, x, y, mi->u.event.id, mi->u.event.value);
|
||||
return;
|
||||
|
||||
done: mtx_unlock(&sysmouse_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
sysmouse_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
|
||||
{
|
||||
void *buf;
|
||||
|
||||
buf = malloc(MOUSE_SYS_PACKETSIZE * SYSMOUSE_MAXFRAMES,
|
||||
M_SYSMOUSE, M_WAITOK);
|
||||
mtx_lock(&sysmouse_lock);
|
||||
if (sysmouse_buffer == NULL) {
|
||||
sysmouse_buffer = buf;
|
||||
sysmouse_start = sysmouse_length = 0;
|
||||
sysmouse_level = 0;
|
||||
} else {
|
||||
free(buf, M_SYSMOUSE);
|
||||
}
|
||||
mtx_unlock(&sysmouse_lock);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sysmouse_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
|
||||
{
|
||||
|
||||
mtx_lock(&sysmouse_lock);
|
||||
free(sysmouse_buffer, M_SYSMOUSE);
|
||||
sysmouse_buffer = NULL;
|
||||
sysmouse_level = 0;
|
||||
mtx_unlock(&sysmouse_lock);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sysmouse_read(struct cdev *dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
unsigned int length;
|
||||
ssize_t oresid;
|
||||
int error = 0;
|
||||
|
||||
oresid = uio->uio_resid;
|
||||
|
||||
mtx_lock(&sysmouse_lock);
|
||||
length = sysmouse_level >= 1 ? MOUSE_SYS_PACKETSIZE :
|
||||
MOUSE_MSC_PACKETSIZE;
|
||||
|
||||
while (uio->uio_resid >= length) {
|
||||
error = sysmouse_buf_read(uio, length);
|
||||
if (error == 0) {
|
||||
/* Process the next frame. */
|
||||
continue;
|
||||
} else if (error != EWOULDBLOCK) {
|
||||
/* Error (e.g. EFAULT). */
|
||||
break;
|
||||
} else {
|
||||
/* Block. */
|
||||
if (oresid != uio->uio_resid || ioflag & O_NONBLOCK)
|
||||
break;
|
||||
error = cv_wait_sig(&sysmouse_sleep, &sysmouse_lock);
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
mtx_unlock(&sysmouse_lock);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
sysmouse_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
|
||||
struct thread *td)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
case FIOASYNC:
|
||||
mtx_lock(&sysmouse_lock);
|
||||
if (*(int *)data)
|
||||
sysmouse_flags |= SM_ASYNC;
|
||||
else
|
||||
sysmouse_flags &= ~SM_ASYNC;
|
||||
mtx_unlock(&sysmouse_lock);
|
||||
return (0);
|
||||
case FIONBIO:
|
||||
return (0);
|
||||
case FIOGETOWN:
|
||||
*(int *)data = fgetown(&sysmouse_sigio);
|
||||
return (0);
|
||||
case FIOSETOWN:
|
||||
return (fsetown(*(int *)data, &sysmouse_sigio));
|
||||
case MOUSE_GETHWINFO: {
|
||||
mousehw_t *hw = (mousehw_t *)data;
|
||||
|
||||
hw->buttons = 10;
|
||||
hw->iftype = MOUSE_IF_SYSMOUSE;
|
||||
hw->type = MOUSE_MOUSE;
|
||||
hw->model = MOUSE_MODEL_GENERIC;
|
||||
hw->hwid = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
case MOUSE_GETLEVEL:
|
||||
*(int *)data = sysmouse_level;
|
||||
return (0);
|
||||
case MOUSE_GETMODE: {
|
||||
mousemode_t *mode = (mousemode_t *)data;
|
||||
|
||||
mode->rate = -1;
|
||||
mode->resolution = -1;
|
||||
mode->accelfactor = 0;
|
||||
mode->level = sysmouse_level;
|
||||
|
||||
switch (mode->level) {
|
||||
case 0:
|
||||
mode->protocol = MOUSE_PROTO_MSC;
|
||||
mode->packetsize = MOUSE_MSC_PACKETSIZE;
|
||||
mode->syncmask[0] = MOUSE_MSC_SYNCMASK;
|
||||
mode->syncmask[1] = MOUSE_MSC_SYNC;
|
||||
break;
|
||||
case 1:
|
||||
mode->protocol = MOUSE_PROTO_SYSMOUSE;
|
||||
mode->packetsize = MOUSE_SYS_PACKETSIZE;
|
||||
mode->syncmask[0] = MOUSE_SYS_SYNCMASK;
|
||||
mode->syncmask[1] = MOUSE_SYS_SYNC;
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
case MOUSE_GETSTATUS:
|
||||
mtx_lock(&sysmouse_lock);
|
||||
*(mousestatus_t *)data = sysmouse_status;
|
||||
|
||||
sysmouse_status.flags = 0;
|
||||
sysmouse_status.obutton = sysmouse_status.button;
|
||||
sysmouse_status.dx = 0;
|
||||
sysmouse_status.dy = 0;
|
||||
sysmouse_status.dz = 0;
|
||||
mtx_unlock(&sysmouse_lock);
|
||||
|
||||
return (0);
|
||||
case MOUSE_SETLEVEL: {
|
||||
int level;
|
||||
|
||||
level = *(int *)data;
|
||||
if (level != 0 && level != 1)
|
||||
return (EINVAL);
|
||||
|
||||
sysmouse_level = level;
|
||||
vt_mouse_state((level == 0)?VT_MOUSE_SHOW:VT_MOUSE_HIDE);
|
||||
return (0);
|
||||
}
|
||||
case MOUSE_SETMODE: {
|
||||
mousemode_t *mode = (mousemode_t *)data;
|
||||
|
||||
switch (mode->level) {
|
||||
case -1:
|
||||
/* Do nothing. */
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
sysmouse_level = mode->level;
|
||||
vt_mouse_state((mode->level == 0)?VT_MOUSE_SHOW:
|
||||
VT_MOUSE_HIDE);
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
case MOUSE_MOUSECHAR:
|
||||
return (0);
|
||||
default:
|
||||
printf("sysmouse: unknown ioctl: %c:%lx\n",
|
||||
(char)IOCGROUP(cmd), IOCBASECMD(cmd));
|
||||
return (ENOIOCTL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
sysmouse_poll(struct cdev *dev, int events, struct thread *td)
|
||||
{
|
||||
int revents = 0;
|
||||
|
||||
mtx_lock(&sysmouse_lock);
|
||||
if (events & (POLLIN|POLLRDNORM)) {
|
||||
if (sysmouse_length > 0)
|
||||
revents = events & (POLLIN|POLLRDNORM);
|
||||
else
|
||||
selrecord(td, &sysmouse_bufpoll);
|
||||
}
|
||||
mtx_unlock(&sysmouse_lock);
|
||||
|
||||
return (revents);
|
||||
}
|
||||
|
||||
static void
|
||||
sysmouse_drvinit(void *unused)
|
||||
{
|
||||
|
||||
mtx_init(&sysmouse_lock, "sysmouse", NULL, MTX_DEF);
|
||||
cv_init(&sysmouse_sleep, "sysmrd");
|
||||
make_dev(&sysmouse_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
|
||||
"sysmouse");
|
||||
}
|
||||
|
||||
SYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sysmouse_drvinit, NULL);
|
602
sys/kern/subr_terminal.c
Normal file
602
sys/kern/subr_terminal.c
Normal file
@ -0,0 +1,602 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Ed Schouten under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/consio.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/terminal.h>
|
||||
#include <sys/tty.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
static MALLOC_DEFINE(M_TERMINAL, "terminal", "terminal device");
|
||||
|
||||
/*
|
||||
* Locking.
|
||||
*
|
||||
* Normally we don't need to lock down the terminal emulator, because
|
||||
* the TTY lock is already held when calling teken_input().
|
||||
* Unfortunately this is not the case when the terminal acts as a
|
||||
* console device, because cnputc() can be called at the same time.
|
||||
* This means terminals may need to be locked down using a spin lock.
|
||||
*/
|
||||
#define TERMINAL_LOCK(tm) do { \
|
||||
if ((tm)->tm_flags & TF_CONS) \
|
||||
mtx_lock_spin(&(tm)->tm_mtx); \
|
||||
else if ((tm)->tm_tty != NULL) \
|
||||
tty_lock((tm)->tm_tty); \
|
||||
} while (0)
|
||||
#define TERMINAL_UNLOCK(tm) do { \
|
||||
if ((tm)->tm_flags & TF_CONS) \
|
||||
mtx_unlock_spin(&(tm)->tm_mtx); \
|
||||
else if ((tm)->tm_tty != NULL) \
|
||||
tty_unlock((tm)->tm_tty); \
|
||||
} while (0)
|
||||
#define TERMINAL_LOCK_TTY(tm) do { \
|
||||
if ((tm)->tm_flags & TF_CONS) \
|
||||
mtx_lock_spin(&(tm)->tm_mtx); \
|
||||
} while (0)
|
||||
#define TERMINAL_UNLOCK_TTY(tm) do { \
|
||||
if ((tm)->tm_flags & TF_CONS) \
|
||||
mtx_unlock_spin(&(tm)->tm_mtx); \
|
||||
} while (0)
|
||||
#define TERMINAL_LOCK_CONS(tm) mtx_lock_spin(&(tm)->tm_mtx)
|
||||
#define TERMINAL_UNLOCK_CONS(tm) mtx_unlock_spin(&(tm)->tm_mtx)
|
||||
|
||||
/*
|
||||
* TTY routines.
|
||||
*/
|
||||
|
||||
static tsw_open_t termtty_open;
|
||||
static tsw_close_t termtty_close;
|
||||
static tsw_outwakeup_t termtty_outwakeup;
|
||||
static tsw_ioctl_t termtty_ioctl;
|
||||
|
||||
static struct ttydevsw terminal_tty_class = {
|
||||
.tsw_open = termtty_open,
|
||||
.tsw_close = termtty_close,
|
||||
.tsw_outwakeup = termtty_outwakeup,
|
||||
.tsw_ioctl = termtty_ioctl,
|
||||
};
|
||||
|
||||
/*
|
||||
* Terminal emulator routines.
|
||||
*/
|
||||
|
||||
static tf_bell_t termteken_bell;
|
||||
static tf_cursor_t termteken_cursor;
|
||||
static tf_putchar_t termteken_putchar;
|
||||
static tf_fill_t termteken_fill;
|
||||
static tf_copy_t termteken_copy;
|
||||
static tf_param_t termteken_param;
|
||||
static tf_respond_t termteken_respond;
|
||||
|
||||
static teken_funcs_t terminal_drawmethods = {
|
||||
.tf_bell = termteken_bell,
|
||||
.tf_cursor = termteken_cursor,
|
||||
.tf_putchar = termteken_putchar,
|
||||
.tf_fill = termteken_fill,
|
||||
.tf_copy = termteken_copy,
|
||||
.tf_param = termteken_param,
|
||||
.tf_respond = termteken_respond,
|
||||
};
|
||||
|
||||
/* Kernel message formatting. */
|
||||
static const teken_attr_t kernel_message = {
|
||||
.ta_fgcolor = TC_WHITE,
|
||||
.ta_bgcolor = TC_BLACK,
|
||||
.ta_format = TF_BOLD,
|
||||
};
|
||||
|
||||
static const teken_attr_t default_message = {
|
||||
.ta_fgcolor = TC_WHITE,
|
||||
.ta_bgcolor = TC_BLACK,
|
||||
};
|
||||
|
||||
#define TCHAR_CREATE(c, a) ((c) | \
|
||||
(a)->ta_format << 22 | \
|
||||
teken_256to8((a)->ta_fgcolor) << 26 | \
|
||||
teken_256to8((a)->ta_bgcolor) << 29)
|
||||
|
||||
static void
|
||||
terminal_init(struct terminal *tm)
|
||||
{
|
||||
|
||||
if (tm->tm_flags & TF_CONS)
|
||||
mtx_init(&tm->tm_mtx, "trmlck", NULL, MTX_SPIN);
|
||||
teken_init(&tm->tm_emulator, &terminal_drawmethods, tm);
|
||||
teken_set_defattr(&tm->tm_emulator, &default_message);
|
||||
}
|
||||
|
||||
struct terminal *
|
||||
terminal_alloc(const struct terminal_class *tc, void *softc)
|
||||
{
|
||||
struct terminal *tm;
|
||||
|
||||
tm = malloc(sizeof(struct terminal), M_TERMINAL, M_WAITOK|M_ZERO);
|
||||
terminal_init(tm);
|
||||
|
||||
tm->tm_class = tc;
|
||||
tm->tm_softc = softc;
|
||||
|
||||
return (tm);
|
||||
}
|
||||
|
||||
static void
|
||||
terminal_sync_ttysize(struct terminal *tm)
|
||||
{
|
||||
struct tty *tp;
|
||||
|
||||
tp = tm->tm_tty;
|
||||
if (tp == NULL)
|
||||
return;
|
||||
|
||||
tty_lock(tp);
|
||||
tty_set_winsize(tp, &tm->tm_winsize);
|
||||
tty_unlock(tp);
|
||||
}
|
||||
|
||||
void
|
||||
terminal_maketty(struct terminal *tm, const char *fmt, ...)
|
||||
{
|
||||
struct tty *tp;
|
||||
char name[8];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnrprintf(name, sizeof name, 32, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
tp = tty_alloc(&terminal_tty_class, tm);
|
||||
tty_makedev(tp, NULL, "%s", name);
|
||||
tm->tm_tty = tp;
|
||||
terminal_sync_ttysize(tm);
|
||||
}
|
||||
|
||||
void
|
||||
terminal_set_winsize_blank(struct terminal *tm, const struct winsize *size,
|
||||
int blank)
|
||||
{
|
||||
term_rect_t r;
|
||||
|
||||
tm->tm_winsize = *size;
|
||||
|
||||
r.tr_begin.tp_row = r.tr_begin.tp_col = 0;
|
||||
r.tr_end.tp_row = size->ws_row;
|
||||
r.tr_end.tp_col = size->ws_col;
|
||||
|
||||
TERMINAL_LOCK(tm);
|
||||
if (blank == 0)
|
||||
teken_set_winsize_noreset(&tm->tm_emulator, &r.tr_end);
|
||||
else
|
||||
teken_set_winsize(&tm->tm_emulator, &r.tr_end);
|
||||
TERMINAL_UNLOCK(tm);
|
||||
|
||||
if (blank != 0)
|
||||
tm->tm_class->tc_fill(tm, &r, TCHAR_CREATE((teken_char_t)' ',
|
||||
&default_message));
|
||||
|
||||
terminal_sync_ttysize(tm);
|
||||
}
|
||||
|
||||
void
|
||||
terminal_set_winsize(struct terminal *tm, const struct winsize *size)
|
||||
{
|
||||
|
||||
terminal_set_winsize_blank(tm, size, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: This function is a kludge. Drivers like vt(4) need to
|
||||
* temporarily stop input when resizing, etc. This should ideally be
|
||||
* handled within the driver.
|
||||
*/
|
||||
|
||||
void
|
||||
terminal_mute(struct terminal *tm, int yes)
|
||||
{
|
||||
|
||||
TERMINAL_LOCK(tm);
|
||||
if (yes)
|
||||
tm->tm_flags |= TF_MUTE;
|
||||
else
|
||||
tm->tm_flags &= ~TF_MUTE;
|
||||
TERMINAL_UNLOCK(tm);
|
||||
}
|
||||
|
||||
void
|
||||
terminal_input_char(struct terminal *tm, term_char_t c)
|
||||
{
|
||||
struct tty *tp;
|
||||
|
||||
tp = tm->tm_tty;
|
||||
if (tp == NULL)
|
||||
return;
|
||||
|
||||
/* Strip off any attributes. */
|
||||
c = TCHAR_CHARACTER(c);
|
||||
|
||||
tty_lock(tp);
|
||||
/*
|
||||
* Conversion to UTF-8.
|
||||
*/
|
||||
if (c < 0x80) {
|
||||
ttydisc_rint(tp, c, 0);
|
||||
} else if (c < 0x800) {
|
||||
char str[2] = {
|
||||
0xc0 | (c >> 6),
|
||||
0x80 | (c & 0x3f)
|
||||
};
|
||||
|
||||
ttydisc_rint_simple(tp, str, sizeof str);
|
||||
} else if (c < 0x10000) {
|
||||
char str[3] = {
|
||||
0xe0 | (c >> 12),
|
||||
0x80 | ((c >> 6) & 0x3f),
|
||||
0x80 | (c & 0x3f)
|
||||
};
|
||||
|
||||
ttydisc_rint_simple(tp, str, sizeof str);
|
||||
} else {
|
||||
char str[4] = {
|
||||
0xf0 | (c >> 18),
|
||||
0x80 | ((c >> 12) & 0x3f),
|
||||
0x80 | ((c >> 6) & 0x3f),
|
||||
0x80 | (c & 0x3f)
|
||||
};
|
||||
|
||||
ttydisc_rint_simple(tp, str, sizeof str);
|
||||
}
|
||||
ttydisc_rint_done(tp);
|
||||
tty_unlock(tp);
|
||||
}
|
||||
|
||||
void
|
||||
terminal_input_raw(struct terminal *tm, char c)
|
||||
{
|
||||
struct tty *tp;
|
||||
|
||||
tp = tm->tm_tty;
|
||||
if (tp == NULL)
|
||||
return;
|
||||
|
||||
tty_lock(tp);
|
||||
ttydisc_rint(tp, c, 0);
|
||||
ttydisc_rint_done(tp);
|
||||
tty_unlock(tp);
|
||||
}
|
||||
|
||||
void
|
||||
terminal_input_special(struct terminal *tm, unsigned int k)
|
||||
{
|
||||
struct tty *tp;
|
||||
const char *str;
|
||||
|
||||
tp = tm->tm_tty;
|
||||
if (tp == NULL)
|
||||
return;
|
||||
|
||||
str = teken_get_sequence(&tm->tm_emulator, k);
|
||||
if (str == NULL)
|
||||
return;
|
||||
|
||||
tty_lock(tp);
|
||||
ttydisc_rint_simple(tp, str, strlen(str));
|
||||
ttydisc_rint_done(tp);
|
||||
tty_unlock(tp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Binding with the TTY layer.
|
||||
*/
|
||||
|
||||
static int
|
||||
termtty_open(struct tty *tp)
|
||||
{
|
||||
struct terminal *tm = tty_softc(tp);
|
||||
|
||||
tm->tm_class->tc_opened(tm, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
termtty_close(struct tty *tp)
|
||||
{
|
||||
struct terminal *tm = tty_softc(tp);
|
||||
|
||||
tm->tm_class->tc_opened(tm, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
termtty_outwakeup(struct tty *tp)
|
||||
{
|
||||
struct terminal *tm = tty_softc(tp);
|
||||
char obuf[128];
|
||||
size_t olen;
|
||||
unsigned int flags = 0;
|
||||
|
||||
while ((olen = ttydisc_getc(tp, obuf, sizeof obuf)) > 0) {
|
||||
TERMINAL_LOCK_TTY(tm);
|
||||
if (!(tm->tm_flags & TF_MUTE)) {
|
||||
tm->tm_flags &= ~TF_BELL;
|
||||
teken_input(&tm->tm_emulator, obuf, olen);
|
||||
flags |= tm->tm_flags;
|
||||
}
|
||||
TERMINAL_UNLOCK_TTY(tm);
|
||||
}
|
||||
|
||||
tm->tm_class->tc_done(tm);
|
||||
if (flags & TF_BELL)
|
||||
tm->tm_class->tc_bell(tm);
|
||||
}
|
||||
|
||||
static int
|
||||
termtty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
|
||||
{
|
||||
struct terminal *tm = tty_softc(tp);
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
case CONS_GETINFO: {
|
||||
vid_info_t *vi = (vid_info_t *)data;
|
||||
const teken_pos_t *p;
|
||||
int fg, bg;
|
||||
|
||||
if (vi->size != sizeof(vid_info_t))
|
||||
return (EINVAL);
|
||||
|
||||
/* Already help the console driver by filling in some data. */
|
||||
p = teken_get_cursor(&tm->tm_emulator);
|
||||
vi->mv_row = p->tp_row;
|
||||
vi->mv_col = p->tp_col;
|
||||
|
||||
p = teken_get_winsize(&tm->tm_emulator);
|
||||
vi->mv_rsz = p->tp_row;
|
||||
vi->mv_csz = p->tp_col;
|
||||
|
||||
teken_get_defattr_cons25(&tm->tm_emulator, &fg, &bg);
|
||||
vi->mv_norm.fore = fg;
|
||||
vi->mv_norm.back = bg;
|
||||
/* XXX: keep vidcontrol happy; bold backgrounds. */
|
||||
vi->mv_rev.fore = bg;
|
||||
vi->mv_rev.back = fg & 0x7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlike various other drivers, this driver will never
|
||||
* deallocate TTYs. This means it's safe to temporarily unlock
|
||||
* the TTY when handling ioctls.
|
||||
*/
|
||||
tty_unlock(tp);
|
||||
error = tm->tm_class->tc_ioctl(tm, cmd, data, td);
|
||||
tty_lock(tp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Binding with the kernel and debug console.
|
||||
*/
|
||||
|
||||
static cn_probe_t termcn_cnprobe;
|
||||
static cn_init_t termcn_cninit;
|
||||
static cn_term_t termcn_cnterm;
|
||||
static cn_getc_t termcn_cngetc;
|
||||
static cn_putc_t termcn_cnputc;
|
||||
static cn_grab_t termcn_cngrab;
|
||||
static cn_ungrab_t termcn_cnungrab;
|
||||
|
||||
const struct consdev_ops termcn_cnops = {
|
||||
.cn_probe = termcn_cnprobe,
|
||||
.cn_init = termcn_cninit,
|
||||
.cn_term = termcn_cnterm,
|
||||
.cn_getc = termcn_cngetc,
|
||||
.cn_putc = termcn_cnputc,
|
||||
.cn_grab = termcn_cngrab,
|
||||
.cn_ungrab = termcn_cnungrab,
|
||||
};
|
||||
|
||||
void
|
||||
termcn_cnregister(struct terminal *tm)
|
||||
{
|
||||
struct consdev *cp;
|
||||
|
||||
cp = tm->consdev;
|
||||
if (cp == NULL) {
|
||||
cp = malloc(sizeof(struct consdev), M_TERMINAL,
|
||||
M_WAITOK|M_ZERO);
|
||||
cp->cn_ops = &termcn_cnops;
|
||||
cp->cn_arg = tm;
|
||||
cp->cn_pri = CN_INTERNAL;
|
||||
sprintf(cp->cn_name, "ttyv0");
|
||||
|
||||
tm->tm_flags = TF_CONS;
|
||||
tm->consdev = cp;
|
||||
|
||||
terminal_init(tm);
|
||||
}
|
||||
|
||||
/* Attach terminal as console. */
|
||||
cnadd(cp);
|
||||
}
|
||||
|
||||
static void
|
||||
termcn_cngrab(struct consdev *cp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
termcn_cnungrab(struct consdev *cp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
termcn_cnprobe(struct consdev *cp)
|
||||
{
|
||||
struct terminal *tm = cp->cn_arg;
|
||||
|
||||
if (tm == NULL) {
|
||||
cp->cn_pri = CN_DEAD;
|
||||
return;
|
||||
}
|
||||
|
||||
tm->consdev = cp;
|
||||
terminal_init(tm);
|
||||
|
||||
tm->tm_class->tc_cnprobe(tm, cp);
|
||||
}
|
||||
|
||||
static void
|
||||
termcn_cninit(struct consdev *cp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
termcn_cnterm(struct consdev *cp)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
termcn_cngetc(struct consdev *cp)
|
||||
{
|
||||
struct terminal *tm = cp->cn_arg;
|
||||
|
||||
return (tm->tm_class->tc_cngetc(tm));
|
||||
}
|
||||
|
||||
static void
|
||||
termcn_cnputc(struct consdev *cp, int c)
|
||||
{
|
||||
struct terminal *tm = cp->cn_arg;
|
||||
teken_attr_t backup;
|
||||
char cv = c;
|
||||
|
||||
TERMINAL_LOCK_CONS(tm);
|
||||
if (!(tm->tm_flags & TF_MUTE)) {
|
||||
backup = *teken_get_curattr(&tm->tm_emulator);
|
||||
teken_set_curattr(&tm->tm_emulator, &kernel_message);
|
||||
teken_input(&tm->tm_emulator, &cv, 1);
|
||||
teken_set_curattr(&tm->tm_emulator, &backup);
|
||||
}
|
||||
TERMINAL_UNLOCK_CONS(tm);
|
||||
|
||||
tm->tm_class->tc_done(tm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Binding with the terminal emulator.
|
||||
*/
|
||||
|
||||
static void
|
||||
termteken_bell(void *softc)
|
||||
{
|
||||
struct terminal *tm = softc;
|
||||
|
||||
tm->tm_flags |= TF_BELL;
|
||||
}
|
||||
|
||||
static void
|
||||
termteken_cursor(void *softc, const teken_pos_t *p)
|
||||
{
|
||||
struct terminal *tm = softc;
|
||||
|
||||
tm->tm_class->tc_cursor(tm, p);
|
||||
}
|
||||
|
||||
static void
|
||||
termteken_putchar(void *softc, const teken_pos_t *p, teken_char_t c,
|
||||
const teken_attr_t *a)
|
||||
{
|
||||
struct terminal *tm = softc;
|
||||
|
||||
tm->tm_class->tc_putchar(tm, p, TCHAR_CREATE(c, a));
|
||||
}
|
||||
|
||||
static void
|
||||
termteken_fill(void *softc, const teken_rect_t *r, teken_char_t c,
|
||||
const teken_attr_t *a)
|
||||
{
|
||||
struct terminal *tm = softc;
|
||||
|
||||
tm->tm_class->tc_fill(tm, r, TCHAR_CREATE(c, a));
|
||||
}
|
||||
|
||||
static void
|
||||
termteken_copy(void *softc, const teken_rect_t *r, const teken_pos_t *p)
|
||||
{
|
||||
struct terminal *tm = softc;
|
||||
|
||||
tm->tm_class->tc_copy(tm, r, p);
|
||||
}
|
||||
|
||||
static void
|
||||
termteken_param(void *softc, int cmd, unsigned int arg)
|
||||
{
|
||||
struct terminal *tm = softc;
|
||||
|
||||
tm->tm_class->tc_param(tm, cmd, arg);
|
||||
}
|
||||
|
||||
static void
|
||||
termteken_respond(void *softc, const void *buf, size_t len)
|
||||
{
|
||||
#if 0
|
||||
struct terminal *tm = softc;
|
||||
struct tty *tp;
|
||||
|
||||
/*
|
||||
* Only inject a response into the TTY if the data actually
|
||||
* originated from the TTY.
|
||||
*
|
||||
* XXX: This cannot be done right now. The TTY could pick up
|
||||
* other locks. It could also in theory cause loops, when the
|
||||
* TTY performs echoing of a command that generates even more
|
||||
* input.
|
||||
*/
|
||||
tp = tm->tm_tty;
|
||||
if (tp == NULL)
|
||||
return;
|
||||
|
||||
ttydisc_rint_simple(tp, buf, len);
|
||||
ttydisc_rint_done(tp);
|
||||
#endif
|
||||
}
|
@ -34,7 +34,7 @@ SRCS = \
|
||||
SRCS += i915_ioc32.c
|
||||
.endif
|
||||
|
||||
SRCS += device_if.h bus_if.h pci_if.h iicbus_if.h iicbb_if.h opt_drm.h \
|
||||
opt_compat.h
|
||||
SRCS += device_if.h fb_if.h bus_if.h pci_if.h iicbus_if.h iicbb_if.h \
|
||||
opt_drm.h opt_compat.h
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -96,6 +96,7 @@ SRCS += \
|
||||
opt_drm.h \
|
||||
acpi_if.h \
|
||||
bus_if.h \
|
||||
fb_if.h \
|
||||
device_if.h \
|
||||
iicbb_if.h \
|
||||
iicbus_if.h \
|
||||
|
@ -556,15 +556,6 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
|
||||
*/
|
||||
sun4u_set_traptable(tl0_base);
|
||||
|
||||
/*
|
||||
* Initialize the console.
|
||||
* NB: the low-level console drivers require a working DELAY() and
|
||||
* some compiler optimizations may cause the curthread accesses of
|
||||
* mutex(9) to be factored out even if the latter aren't actually
|
||||
* called, both requiring PCPU_REG to be set.
|
||||
*/
|
||||
cninit();
|
||||
|
||||
/*
|
||||
* Initialize the dynamic per-CPU area for the BSP and the message
|
||||
* buffer (after setting the trap table).
|
||||
@ -577,6 +568,12 @@ sparc64_init(caddr_t mdp, u_long o1, u_long o2, u_long o3, ofw_vec_t *vec)
|
||||
*/
|
||||
mutex_init();
|
||||
|
||||
/*
|
||||
* Initialize console now that we have a reasonable set of system
|
||||
* services.
|
||||
*/
|
||||
cninit();
|
||||
|
||||
/*
|
||||
* Finish the interrupt initialization now that mutexes work and
|
||||
* enable them.
|
||||
|
@ -209,12 +209,33 @@ struct fnt16 {
|
||||
};
|
||||
typedef struct fnt16 fnt16_t;
|
||||
|
||||
struct vfnt_map {
|
||||
uint32_t src;
|
||||
uint16_t dst;
|
||||
uint16_t len;
|
||||
};
|
||||
typedef struct vfnt_map vfnt_map_t;
|
||||
|
||||
struct vfnt {
|
||||
vfnt_map_t *normal;
|
||||
vfnt_map_t *bold;
|
||||
uint8_t *glyphs;
|
||||
unsigned int nnormal;
|
||||
unsigned int nbold;
|
||||
unsigned int nglyphs;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
};
|
||||
typedef struct vfnt vfnt_t;
|
||||
|
||||
#define PIO_FONT8x8 _IOW('c', 64, fnt8_t)
|
||||
#define GIO_FONT8x8 _IOR('c', 65, fnt8_t)
|
||||
#define PIO_FONT8x14 _IOW('c', 66, fnt14_t)
|
||||
#define GIO_FONT8x14 _IOR('c', 67, fnt14_t)
|
||||
#define PIO_FONT8x16 _IOW('c', 68, fnt16_t)
|
||||
#define GIO_FONT8x16 _IOR('c', 69, fnt16_t)
|
||||
#define PIO_VFONT _IOW('c', 70, vfnt_t)
|
||||
#define GIO_VFONT _IOR('c', 71, vfnt_t)
|
||||
|
||||
/* get video mode information */
|
||||
struct colors {
|
||||
|
@ -262,4 +262,12 @@ EVENTHANDLER_DECLARE(kld_load, kld_load_fn);
|
||||
EVENTHANDLER_DECLARE(kld_unload, kld_unload_fn);
|
||||
EVENTHANDLER_DECLARE(kld_unload_try, kld_unload_try_fn);
|
||||
|
||||
/* Generic graphics framebuffer interface */
|
||||
struct fb_info;
|
||||
typedef void (*register_framebuffer_fn)(void *, struct fb_info *);
|
||||
typedef void (*unregister_framebuffer_fn)(void *, struct fb_info *);
|
||||
EVENTHANDLER_DECLARE(register_framebuffer, register_framebuffer_fn);
|
||||
EVENTHANDLER_DECLARE(unregister_framebuffer, unregister_framebuffer_fn);
|
||||
|
||||
#endif /* _SYS_EVENTHANDLER_H_ */
|
||||
|
||||
|
@ -40,6 +40,10 @@
|
||||
|
||||
#ifndef _KERNEL
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#endif
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
@ -101,6 +105,78 @@ struct fbtype {
|
||||
};
|
||||
#define FBIOGTYPE _IOR('F', 0, struct fbtype)
|
||||
|
||||
#define FBTYPE_GET_STRIDE(_fb) ((_fb)->fb_size / (_fb)->fb_height)
|
||||
#define FBTYPE_GET_BPP(_fb) ((_fb)->fb_bpp)
|
||||
#define FBTYPE_GET_BYTESPP(_fb) ((_fb)->fb_bpp / 8)
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct fb_info;
|
||||
|
||||
typedef int fb_enter_t(void *priv);
|
||||
typedef int fb_leave_t(void *priv);
|
||||
typedef int fb_write_t(void *priv, int offset, void *data, int size);
|
||||
typedef int fb_read_t(void *priv, int offset, void *data, int size);
|
||||
|
||||
/* XXX: should use priv instead of fb_info too. */
|
||||
typedef void fb_copy_t(struct fb_info *sc, uint32_t offset_to, uint32_t offset_from,
|
||||
uint32_t size);
|
||||
typedef void fb_wr1_t(struct fb_info *sc, uint32_t offset, uint8_t value);
|
||||
typedef void fb_wr2_t(struct fb_info *sc, uint32_t offset, uint16_t value);
|
||||
typedef void fb_wr4_t(struct fb_info *sc, uint32_t offset, uint32_t value);
|
||||
|
||||
struct fb_info {
|
||||
/* Raw copy of fbtype. Do not change. */
|
||||
int fb_type; /* as defined above */
|
||||
int fb_height; /* in pixels */
|
||||
int fb_width; /* in pixels */
|
||||
int fb_depth; /* bits to define color */
|
||||
int fb_cmsize; /* size of color map (entries) */
|
||||
int fb_size; /* total size in bytes */
|
||||
|
||||
/* Methods. */
|
||||
fb_write_t *fb_write; /* if NULL, direct mem write. */
|
||||
fb_read_t *fb_read; /* if NULL, direct mem read. */
|
||||
|
||||
fb_wr1_t *wr1;
|
||||
fb_wr2_t *wr2;
|
||||
fb_wr4_t *wr4;
|
||||
fb_copy_t *copy;
|
||||
fb_enter_t *enter;
|
||||
fb_leave_t *leave;
|
||||
|
||||
intptr_t fb_pbase; /* For FB mmap. */
|
||||
intptr_t fb_vbase; /* if NULL, use fb_write/fb_read. */
|
||||
void *fb_priv; /* First argument for read/write. */
|
||||
const char *fb_name;
|
||||
uint32_t fb_flags;
|
||||
int fb_stride;
|
||||
int fb_bpp; /* bits per pixel */
|
||||
#define FB_FLAG_NOMMAP 1 /* mmap unsupported. */
|
||||
uint32_t fb_cmap[16];
|
||||
};
|
||||
|
||||
int fbd_list(void);
|
||||
int fbd_register(struct fb_info *);
|
||||
int fbd_unregister(struct fb_info *);
|
||||
|
||||
static inline int
|
||||
register_framebuffer(struct fb_info *info)
|
||||
{
|
||||
|
||||
EVENTHANDLER_INVOKE(register_framebuffer, info);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
unregister_framebuffer(struct fb_info *info)
|
||||
{
|
||||
|
||||
EVENTHANDLER_INVOKE(unregister_framebuffer, info);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* General purpose structure for passing info in and out of frame buffers
|
||||
|
161
sys/sys/terminal.h
Normal file
161
sys/sys/terminal.h
Normal file
@ -0,0 +1,161 @@
|
||||
/*-
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Ed Schouten under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _SYS_TERMINAL_H_
|
||||
#define _SYS_TERMINAL_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/_lock.h>
|
||||
#include <sys/_mutex.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/linker_set.h>
|
||||
#include <sys/ttycom.h>
|
||||
|
||||
#include <teken/teken.h>
|
||||
|
||||
struct terminal;
|
||||
struct thread;
|
||||
struct tty;
|
||||
|
||||
/*
|
||||
* The terminal layer is an abstraction on top of the TTY layer and the
|
||||
* console interface. It can be used by system console drivers to
|
||||
* easily interact with the kernel console and TTYs.
|
||||
*
|
||||
* Terminals contain terminal emulators, which means console drivers
|
||||
* don't need to implement their own terminal emulator. The terminal
|
||||
* emulator deals with UTF-8 exclusively. This means that term_char_t,
|
||||
* the data type used to store input/output characters will always
|
||||
* contain Unicode codepoints.
|
||||
*
|
||||
* To save memory usage, the top bits of term_char_t will contain other
|
||||
* attributes, like colors. Right now term_char_t is composed as
|
||||
* follows:
|
||||
*
|
||||
* Bits Meaning
|
||||
* 0-20: Character value
|
||||
* 21: Unused
|
||||
* 22-25: Bold, underline, blink, reverse
|
||||
* 26-28: Foreground color
|
||||
* 29-31: Background color
|
||||
*/
|
||||
|
||||
typedef uint32_t term_char_t;
|
||||
#define TCHAR_CHARACTER(c) ((c) & 0x1fffff)
|
||||
#define TCHAR_FORMAT(c) (((c) >> 22) & 0xf)
|
||||
#define TCHAR_FGCOLOR(c) (((c) >> 26) & 0x7)
|
||||
#define TCHAR_BGCOLOR(c) ((c) >> 29)
|
||||
|
||||
typedef teken_color_t term_color_t;
|
||||
#define TCOLOR_LIGHT(c) ((c) | 0x8)
|
||||
#define TCOLOR_DARK(c) ((c) & ~0x8)
|
||||
typedef teken_pos_t term_pos_t;
|
||||
typedef teken_rect_t term_rect_t;
|
||||
|
||||
typedef void tc_cursor_t(struct terminal *tm, const term_pos_t *p);
|
||||
typedef void tc_putchar_t(struct terminal *tm, const term_pos_t *p,
|
||||
term_char_t c);
|
||||
typedef void tc_fill_t(struct terminal *tm, const term_rect_t *r,
|
||||
term_char_t c);
|
||||
typedef void tc_copy_t(struct terminal *tm, const term_rect_t *r,
|
||||
const term_pos_t *p);
|
||||
typedef void tc_param_t(struct terminal *tm, int cmd, unsigned int arg);
|
||||
typedef void tc_done_t(struct terminal *tm);
|
||||
|
||||
typedef void tc_cnprobe_t(struct terminal *tm, struct consdev *cd);
|
||||
typedef int tc_cngetc_t(struct terminal *tm);
|
||||
|
||||
typedef void tc_opened_t(struct terminal *tm, int opened);
|
||||
typedef int tc_ioctl_t(struct terminal *tm, u_long cmd, caddr_t data,
|
||||
struct thread *td);
|
||||
typedef void tc_bell_t(struct terminal *tm);
|
||||
|
||||
struct terminal_class {
|
||||
/* Terminal emulator. */
|
||||
tc_cursor_t *tc_cursor;
|
||||
tc_putchar_t *tc_putchar;
|
||||
tc_fill_t *tc_fill;
|
||||
tc_copy_t *tc_copy;
|
||||
tc_param_t *tc_param;
|
||||
tc_done_t *tc_done;
|
||||
|
||||
/* Low-level console interface. */
|
||||
tc_cnprobe_t *tc_cnprobe;
|
||||
tc_cngetc_t *tc_cngetc;
|
||||
|
||||
/* Misc. */
|
||||
tc_opened_t *tc_opened;
|
||||
tc_ioctl_t *tc_ioctl;
|
||||
tc_bell_t *tc_bell;
|
||||
};
|
||||
|
||||
struct terminal {
|
||||
const struct terminal_class *tm_class;
|
||||
void *tm_softc;
|
||||
struct mtx tm_mtx;
|
||||
struct tty *tm_tty;
|
||||
teken_t tm_emulator;
|
||||
struct winsize tm_winsize;
|
||||
unsigned int tm_flags;
|
||||
#define TF_MUTE 0x1 /* Drop incoming data. */
|
||||
#define TF_BELL 0x2 /* Bell needs to be sent. */
|
||||
#define TF_CONS 0x4 /* Console device (needs spinlock). */
|
||||
struct consdev *consdev;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
struct terminal *terminal_alloc(const struct terminal_class *tc, void *softc);
|
||||
void terminal_maketty(struct terminal *tm, const char *fmt, ...);
|
||||
void terminal_set_winsize_blank(struct terminal *tm,
|
||||
const struct winsize *size, int blank);
|
||||
void terminal_set_winsize(struct terminal *tm, const struct winsize *size);
|
||||
void terminal_mute(struct terminal *tm, int yes);
|
||||
void terminal_input_char(struct terminal *tm, term_char_t c);
|
||||
void terminal_input_raw(struct terminal *tm, char c);
|
||||
void terminal_input_special(struct terminal *tm, unsigned int k);
|
||||
|
||||
void termcn_cnregister(struct terminal *tm);
|
||||
|
||||
/* Kernel console helper interface. */
|
||||
extern const struct consdev_ops termcn_cnops;
|
||||
|
||||
#define TERMINAL_DECLARE_EARLY(name, class, softc) \
|
||||
static struct terminal name = { \
|
||||
.tm_class = &class, \
|
||||
.tm_softc = softc, \
|
||||
.tm_flags = TF_CONS, \
|
||||
}; \
|
||||
CONSOLE_DEVICE(name ## _consdev, termcn_cnops, &name)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_SYS_TERMINAL_H_ */
|
@ -166,6 +166,7 @@ void tty_rel_gone(struct tty *tp);
|
||||
|
||||
#define tty_lock(tp) mtx_lock((tp)->t_mtx)
|
||||
#define tty_unlock(tp) mtx_unlock((tp)->t_mtx)
|
||||
#define tty_lock_owned(tp) mtx_owned((tp)->t_mtx)
|
||||
#define tty_lock_assert(tp,ma) mtx_assert((tp)->t_mtx, (ma))
|
||||
#define tty_getlock(tp) ((tp)->t_mtx)
|
||||
|
||||
|
@ -346,6 +346,14 @@ teken_set_winsize(teken_t *t, const teken_pos_t *p)
|
||||
teken_subr_do_reset(t);
|
||||
}
|
||||
|
||||
void
|
||||
teken_set_winsize_noreset(teken_t *t, const teken_pos_t *p)
|
||||
{
|
||||
|
||||
t->t_winsize = *p;
|
||||
teken_subr_do_resize(t);
|
||||
}
|
||||
|
||||
void
|
||||
teken_set_8bit(teken_t *t)
|
||||
{
|
||||
|
@ -168,6 +168,7 @@ void teken_set_cursor(teken_t *, const teken_pos_t *);
|
||||
void teken_set_curattr(teken_t *, const teken_attr_t *);
|
||||
void teken_set_defattr(teken_t *, const teken_attr_t *);
|
||||
void teken_set_winsize(teken_t *, const teken_pos_t *);
|
||||
void teken_set_winsize_noreset(teken_t *, const teken_pos_t *);
|
||||
|
||||
/* Key input escape sequences. */
|
||||
#define TKEY_UP 0x00
|
||||
|
@ -955,6 +955,15 @@ teken_subr_reset_mode(teken_t *t, unsigned int cmd)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_do_resize(teken_t *t)
|
||||
{
|
||||
|
||||
t->t_scrollreg.ts_begin = 0;
|
||||
t->t_scrollreg.ts_end = t->t_winsize.tp_row;
|
||||
t->t_originreg = t->t_scrollreg;
|
||||
}
|
||||
|
||||
static void
|
||||
teken_subr_do_reset(teken_t *t)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user