176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <string.h>
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <stdio.h>
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <lib/sys/vesa/vesa.h>
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include "sysdump.h"
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanvoid dump_vesa_tables(struct upload_backend *be)
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman{
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    com32sys_t rm;
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct vesa_info *vip;
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct vesa_general_info *gip, gi;
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    struct vesa_mode_info *mip, mi;
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    uint16_t mode, *mode_ptr;
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    char modefile[64];
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    printf("Scanning VESA BIOS... ");
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    /* Allocate space in the bounce buffer for these structures */
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    vip = lmalloc(sizeof *vip);
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    gip = &vip->gi;
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    mip = &vip->mi;
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(&rm, 0, sizeof rm);
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memset(gip, 0, sizeof *gip);
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    gip->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    rm.eax.w[0] = 0x4F00;		/* Get SVGA general information */
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    rm.edi.w[0] = OFFS(gip);
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    rm.es = SEG(gip);
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    __intcall(0x10, &rm, &rm);
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    memcpy(&gi, gip, sizeof gi);
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (rm.eax.w[0] != 0x004F)
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return;		/* Function call failed */
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    if (gi.signature != VESA_MAGIC)
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	return;		/* No magic */
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    cpio_mkdir(be, "vesa");
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    cpio_writefile(be, "vesa/global.bin", &gi, sizeof gi);
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    mode_ptr = GET_PTR(gi.video_mode_ptr);
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    while ((mode = *mode_ptr++) != 0xFFFF) {
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memset(mip, 0, sizeof *mip);
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman        memset(&rm, 0, sizeof rm);
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rm.ecx.w[0] = mode;
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rm.edi.w[0] = OFFS(mip);
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	rm.es = SEG(mip);
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	__intcall(0x10, &rm, &rm);
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	/* Must be a supported mode */
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	if (rm.eax.w[0] != 0x004f)
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	    continue;
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	memcpy(&mi, mip, sizeof mi);
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	sprintf(modefile, "vesa/mode%04x.bin", mode);
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman	cpio_writefile(be, modefile, &mi, sizeof mi);
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    }
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    lfree(vip);
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman    printf("done.\n");
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}
64