Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting a custom modeline with incorrect syntax crashes the board #469

Open
tdaede opened this issue May 7, 2019 · 1 comment
Open

Setting a custom modeline with incorrect syntax crashes the board #469

tdaede opened this issue May 7, 2019 · 1 comment

Comments

@tdaede
Copy link

tdaede commented May 7, 2019

H2U 00:00:05>m custom 
Parsing custom mode...
Failed to set custom mode - values out of range.
Aborted.

It shouldn't require resetting the board if a typo is made.

@mithro
Copy link
Member

mithro commented May 8, 2019

@tdaede Agreed that it shouldn't cause the system to lock up. Want to see if you can fix it?

The parsing code is at

static void video_mode_custom(char* str)
{
wprintf("Parsing custom mode...\n");
char* token;
// Modeline "String description" Dot-Clock HDisp HSyncStart HSyncEnd HTotal VDisp VSyncStart VSyncEnd VTotal [options]
// $ xrandr --newmode "1280x1024_60.00" 109.00 1280 1368 1496 1712 1024 1027 1034 1063 -hsync +vsync
// Based on code from http://cgit.freedesktop.org/xorg/app/xrandr/tree/xrandr.c#n3101
NEXT_TOKEN_OR_RETURN(str, token);
char* dotClockInt = get_token_generic(&token, '.');
char* dotClockDec = get_token(&token);
if (!dotClockInt || !dotClockDec) return;
unsigned int dotClock = (atoi(dotClockInt) * 100) + atoi(dotClockDec);
NEXT_TOKEN_OR_RETURN(str, token);
unsigned int width = atoi(token);
NEXT_TOKEN_OR_RETURN(str, token);
unsigned int hSyncStart = atoi(token);
NEXT_TOKEN_OR_RETURN(str, token);
unsigned int hSyncEnd = atoi(token);
NEXT_TOKEN_OR_RETURN(str, token);
unsigned int hTotal = atoi(token);
NEXT_TOKEN_OR_RETURN(str, token);
unsigned int height = atoi(token);
NEXT_TOKEN_OR_RETURN(str, token);
unsigned int vSyncStart = atoi(token);
NEXT_TOKEN_OR_RETURN(str, token);
unsigned int vSyncEnd = atoi(token);
NEXT_TOKEN_OR_RETURN(str, token);
unsigned int vTotal = atoi(token);
unsigned int modeFlags = EDID_DIGITAL; // Always Digital Separate
while (*str != '\0') {
token = get_token(&str);
if (*token == '\0' && *str == '\0') break;
int f;
for (f = 0; timing_mode_flags[f].string; f++)
if (strcasecmp(timing_mode_flags[f].string, token) == 0)
break;
if (!timing_mode_flags[f].string) {
if (*token != '\0') {
wprintf("Skipping flag: %s\n", token);
continue;
}
break;
}
modeFlags |= timing_mode_flags[f].flag;
}
/*
-------------------> Time ------------->
+-------------------+
Video | Blanking | Video
| |
----(a)--------->|<-------(b)------->|
| |
| +-------+ |
| | Sync | |
| | | |
|<-(c)->|<-(d)->| |
| | | |
----(1)--------->| | | |
----(2)----------------->| | |
----(3)------------------------->| |
----(4)----------------------------->|
| | | |
-----------------\ /--------
| |
\-------\ /---/
| |
\-------/
(a) - h_active
(b) - h_blanking
(c) - h_sync_offset
(d) - h_sync_width
(1) - HDisp / width
(2) - HSyncStart
(3) - HSyncEnd
(4) - HTotal
*/
if (hTotal <= hSyncEnd || hSyncEnd <= hSyncStart ||
hSyncStart <= width || vTotal <= vSyncEnd ||
vSyncEnd <= vSyncStart || vSyncStart <= height) {
wprintf("Failed to set custom mode - values out of range.\n");
}
struct video_timing* mode = processor_get_custom_mode();
// 640x480 @ 75Hz (VESA) hsync: 37.5kHz
// Modeline "String des" Dot-Clock HDisp HSyncStart HSyncEnd HTotal VDisp VSyncStart VSyncEnd VTotal [options]
// ModeLine "640x480" 31.5 640 656 720 840 480 481 484 500
// 16 64 <200 1 3 <20
mode->pixel_clock = dotClock;
mode->h_active = width;
mode->h_blanking = hTotal - width;
mode->h_sync_offset = hSyncStart - hTotal;
mode->h_sync_width = hSyncEnd - hSyncStart;
mode->v_active = height;
mode->v_blanking = vTotal - height;
mode->v_sync_offset = vSyncStart - height;
mode->v_sync_width = vSyncEnd - vSyncStart;
mode->flags = modeFlags;
processor_set_custom_mode();
wprintf("Custom video mode set.\n");
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants