示例#1
0
int
vesafb_get_ddc_info(struct vga_pci_softc *sc, struct edid *info)
{
	struct trapframe tf;
	unsigned char *buf;
	int res;

	if ((buf = kvm86_bios_addpage(KVM86_CALL_TASKVA)) == NULL) {
		printf("%s: kvm86_bios_addpage failed.\n",
		    sc->sc_dev.dv_xname);
		return 1;
	}

	bzero(&tf, sizeof(struct trapframe));
	tf.tf_eax = VBE_FUNC_DDC;
	tf.tf_ebx = VBE_DDC_GET;
	tf.tf_vm86_es = 0;
	tf.tf_edi = KVM86_CALL_TASKVA;

	res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
	if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
		kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
		return 1;
	}

	memcpy(info, buf, sizeof(struct edid));
	kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
	return VBECALL_SUCCESS(tf.tf_eax);
}
示例#2
0
void
vesafb_set_palette(struct vga_pci_softc *sc, int reg, struct paletteentry *pe)
{
	struct trapframe tf;
	int res;
	char *buf;

	if ((buf = kvm86_bios_addpage(KVM86_CALL_TASKVA)) == NULL) {
		printf("%s: kvm86_bios_addpage failed.\n",
		       sc->sc_dev.dv_xname);
		return;
	}

	memcpy(buf, pe, sizeof(struct paletteentry));

	/*
	 * this function takes 8 bit per palette as input, but we're
	 * working in 6 bit mode here
	 */
	pe = (struct paletteentry *)buf; 
	pe->Red >>= 2;
	pe->Green >>= 2;
	pe->Blue >>= 2;

	/* set palette */
	memset(&tf, 0, sizeof(struct trapframe));
	tf.tf_eax = VBE_FUNC_PALETTE;
	tf.tf_ebx = 0x0600; /* 6 bit per primary, set format */
	tf.tf_ecx = 1;
	tf.tf_edx = reg;
	tf.tf_vm86_es = 0;
	tf.tf_edi = KVM86_CALL_TASKVA;

	res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
	if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED)
		printf("%s: vbecall: res=%d, ax=%x\n",
		    sc->sc_dev.dv_xname, res, tf.tf_eax);

	kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
	return;
}
示例#3
0
int
vbegetinfo(struct vbeinfoblock **vip)
{
    unsigned char *buf;
    struct trapframe tf;
    int res, error;

    if ((buf = kvm86_bios_addpage(KVM86_CALL_TASKVA)) == NULL) {
        printf("vbegetinfo: kvm86_bios_addpage failed\n");
        return (ENOMEM);
    }

    memcpy(buf, "VBE2", 4);

    memset(&tf, 0, sizeof(struct trapframe));
    tf.tf_eax = VBE_FUNC_CTRLINFO;
    tf.tf_vm86_es = 0;
    tf.tf_edi = KVM86_CALL_TASKVA;

    res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
    if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
        printf("vbecall: res=%d, ax=%x\n", res, tf.tf_eax);
        error = ENXIO;
        goto out;
    }

    if (memcmp(((struct vbeinfoblock *)buf)->VbeSignature, "VESA", 4)) {
        error = EIO;
        goto out;
    }

    if (vip)
        *vip = (struct vbeinfoblock *)buf;
    return (0);

out:
    kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
    return (error);
}
示例#4
0
void
vesabios_attach(struct device *parent, struct device *self, void *aux)
{
    struct vesabios_softc *sc = (struct vesabios_softc *)self;
    struct vbeinfoblock *vi;
    unsigned char *buf;
    struct trapframe tf;
    int res;
    char name[256];
#define MAXMODES 60
    uint16_t modes[MAXMODES];
    int rastermodes[MAXMODES];
    int textmodes[MAXMODES];
    int nmodes, nrastermodes, ntextmodes, i;
    uint32_t modeptr;
    struct modeinfoblock *mi;

    if (vbegetinfo(&vi)) {
        printf("\n");
        panic("vesabios_attach: disappeared");
    }

    printf(": version %d.%d",
           VBE_CTRLINFO_VERSION(vi->VbeVersion),
           VBE_CTRLINFO_REVISION(vi->VbeVersion));


    res = kvm86_bios_read(FAR2FLATPTR(vi->OemVendorNamePtr),
                          name, sizeof(name));

    sc->sc_size = vi->TotalMemory * 65536;
    if (res > 0) {
        name[res - 1] = 0;
        printf(", %s", name);
        res = kvm86_bios_read(FAR2FLATPTR(vi->OemProductNamePtr),
                              name, sizeof(name));
        if (res > 0) {
            name[res - 1] = 0;
            printf(" %s", name);
        }
    }
    printf("\n");

    nmodes = 0;
    modeptr = FAR2FLATPTR(vi->VideoModePtr);
    while (nmodes < MAXMODES) {
        res = kvm86_bios_read(modeptr, (char *)&modes[nmodes], 2);
        if (res != 2 || modes[nmodes] == 0xffff)
            break;
        nmodes++;
        modeptr += 2;
    }

    vbefreeinfo(vi);
    if (nmodes == 0)
        return;

    nrastermodes = ntextmodes = 0;

    buf = kvm86_bios_addpage(KVM86_CALL_TASKVA);
    if (!buf) {
        printf("%s: kvm86_bios_addpage failed\n",
               self->dv_xname);
        return;
    }
    for (i = 0; i < nmodes; i++) {

        memset(&tf, 0, sizeof(struct trapframe));
        tf.tf_eax = VBE_FUNC_MODEINFO;
        tf.tf_ecx = modes[i];
        tf.tf_vm86_es = 0;
        tf.tf_edi = KVM86_CALL_TASKVA;

        res = kvm86_bioscall(BIOS_VIDEO_INTR, &tf);
        if (res || VBECALL_SUPPORT(tf.tf_eax) != VBECALL_SUPPORTED) {
            printf("%s: vbecall: res=%d, ax=%x\n",
                   self->dv_xname, res, tf.tf_eax);
            printf("%s: error getting info for mode %04x\n",
                   self->dv_xname, modes[i]);
            continue;
        }
        mi = (struct modeinfoblock *)buf;
#ifdef VESABIOSVERBOSE
        printf("%s: VESA mode %04x: attributes %04x",
               self->dv_xname, modes[i], mi->ModeAttributes);
#endif
        if (!(mi->ModeAttributes & 1)) {
#ifdef VESABIOSVERBOSE
            printf("\n");
#endif
            continue;
        }
        if (mi->ModeAttributes & 0x10) {
            /* graphics */
#ifdef VESABIOSVERBOSE
            printf(", %dx%d %dbbp %s\n",
                   mi->XResolution, mi->YResolution,
                   mi->BitsPerPixel, mm2txt(mi->MemoryModel));
#endif
            if (mi->ModeAttributes & 0x80) {
                /* flat buffer */
                rastermodes[nrastermodes++] = modes[i];
            }
        } else {
            /* text */
#ifdef VESABIOSVERBOSE
            printf(", text %dx%d\n",
                   mi->XResolution, mi->YResolution);
#endif
            if (!(mi->ModeAttributes & 0x20)) /* VGA compatible */
                textmodes[ntextmodes++] = modes[i];
        }
    }
    kvm86_bios_delpage(KVM86_CALL_TASKVA, buf);
    if (nrastermodes > 0) {
        sc->sc_modes =
            (uint16_t *)malloc(sizeof(uint16_t)*nrastermodes,
                               M_DEVBUF, M_NOWAIT);
        if (sc->sc_modes == NULL) {
            sc->sc_nmodes = 0;
            return;
        }
        sc->sc_nmodes = nrastermodes;
        for (i = 0; i < nrastermodes; i++)
            sc->sc_modes[i] = rastermodes[i];
    }
    vesabios_softc = sc;
}