diff options
Diffstat (limited to 'contrib/syslinux-4.02/com32/lib/sys')
59 files changed, 6229 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/com32/lib/sys/ansi.c b/contrib/syslinux-4.02/com32/lib/sys/ansi.c new file mode 100644 index 0000000..f73c03e --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/ansi.c @@ -0,0 +1,444 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * ansi.c + * + * ANSI character code engine + */ + +#include <string.h> +#include <colortbl.h> +#include "ansi.h" + +static const struct term_state default_state = { + .state = st_init, + .pvt = false, + .nparms = 0, + .xy = {0, 0}, + .cindex = 0, /* First color table entry */ + .vtgraphics = false, + .intensity = 1, + .underline = false, + .blink = false, + .reverse = false, + .fg = 7, + .bg = 0, + .autocr = true, /* Mimic \n -> \r\n conversion by default */ + .autowrap = true, /* Wrap lines by default */ + .saved_xy = {0, 0}, + .cursor = true, +}; + +/* DEC VT graphics to codepage 437 table (characters 0x60-0x7F only) */ +static const char decvt_to_cp437[] = { + 0004, 0261, 0007, 0007, 0007, 0007, 0370, 0361, + 0007, 0007, 0331, 0277, 0332, 0300, 0305, 0304, + 0304, 0304, 0137, 0137, 0303, 0264, 0301, 0302, + 0263, 0363, 0362, 0343, 0330, 0234, 0007, 00 +}; + +void __ansi_init(const struct term_info *ti) +{ + memcpy(ti->ts, &default_state, sizeof default_state); +} + +void __ansi_putchar(const struct term_info *ti, uint8_t ch) +{ + const struct ansi_ops *op = ti->op; + struct term_state *st = ti->ts; + const int rows = ti->rows; + const int cols = ti->cols; + struct curxy xy = st->xy; + + switch (st->state) { + case st_init: + switch (ch) { + case 1 ... 5: + st->state = st_tbl; + st->parms[0] = ch; + break; + case '\a': + op->beep(); + break; + case '\b': + if (xy.x > 0) + xy.x--; + break; + case '\t': + { + int nsp = 8 - (xy.x & 7); + while (nsp--) + __ansi_putchar(ti, ' '); + } + return; /* Cursor already updated */ + case '\n': + case '\v': + case '\f': + xy.y++; + if (st->autocr) + xy.x = 0; + break; + case '\r': + xy.x = 0; + break; + case 127: + /* Ignore delete */ + break; + case 14: + st->vtgraphics = 1; + break; + case 15: + st->vtgraphics = 0; + break; + case 27: + st->state = st_esc; + break; + default: + /* Print character */ + if (ch >= 32) { + if (st->vtgraphics && (ch & 0xe0) == 0x60) + ch = decvt_to_cp437[ch - 0x60]; + + op->write_char(xy.x, xy.y, ch, st); + xy.x++; + } + break; + } + break; + + case st_esc: + switch (ch) { + case '%': + case '(': + case ')': + case '#': + /* Ignore this plus the subsequent character, allows + compatibility with Linux sequence to set charset */ + break; + case '[': + st->state = st_csi; + st->nparms = 0; + st->pvt = false; + memset(st->parms, 0, sizeof st->parms); + break; + case 'c': + /* Reset terminal */ + memcpy(&st, &default_state, sizeof st); + op->erase(st, 0, 0, cols - 1, rows - 1); + xy.x = xy.y = 0; + st->state = st_init; + break; + default: + /* Ignore sequence */ + st->state = st_init; + break; + } + break; + + case st_csi: + { + int p0 = st->parms[0] ? st->parms[0] : 1; + + if (ch >= '0' && ch <= '9') { + st->parms[st->nparms] = st->parms[st->nparms] * 10 + (ch - '0'); + } else if (ch == ';') { + st->nparms++; + if (st->nparms >= ANSI_MAX_PARMS) + st->nparms = ANSI_MAX_PARMS - 1; + break; + } else if (ch == '?') { + st->pvt = true; + } else { + switch (ch) { + case 'A': + { + int y = xy.y - p0; + xy.y = (y < 0) ? 0 : y; + } + break; + case 'B': + { + int y = xy.y + p0; + xy.y = (y >= rows) ? rows - 1 : y; + } + break; + case 'C': + { + int x = xy.x + p0; + xy.x = (x >= cols) ? cols - 1 : x; + } + break; + case 'D': + { + int x = xy.x - p0; + xy.x = (x < 0) ? 0 : x; + } + break; + case 'E': + { + int y = xy.y + p0; + xy.y = (y >= rows) ? rows - 1 : y; + xy.x = 0; + } + break; + case 'F': + { + int y = xy.y - p0; + xy.y = (y < 0) ? 0 : y; + xy.x = 0; + } + break; + case 'G': + case '\'': + { + int x = st->parms[0] - 1; + xy.x = (x >= cols) ? cols - 1 : (x < 0) ? 0 : x; + } + break; + case 'H': + case 'f': + { + int y = st->parms[0] - 1; + int x = st->parms[1] - 1; + + xy.x = (x >= cols) ? cols - 1 : (x < 0) ? 0 : x; + xy.y = (y >= rows) ? rows - 1 : (y < 0) ? 0 : y; + } + break; + case 'J': + { + switch (st->parms[0]) { + case 0: + op->erase(st, xy.x, xy.y, cols - 1, xy.y); + if (xy.y < rows - 1) + op->erase(st, 0, xy.y + 1, cols - 1, rows - 1); + break; + + case 1: + if (xy.y > 0) + op->erase(st, 0, 0, cols - 1, xy.y - 1); + if (xy.y > 0) + op->erase(st, 0, xy.y, xy.x - 1, xy.y); + break; + + case 2: + op->erase(st, 0, 0, cols - 1, rows - 1); + break; + + default: + /* Ignore */ + break; + } + } + break; + case 'K': + { + switch (st->parms[0]) { + case 0: + op->erase(st, xy.x, xy.y, cols - 1, xy.y); + break; + + case 1: + if (xy.x > 0) + op->erase(st, 0, xy.y, xy.x - 1, xy.y); + break; + + case 2: + op->erase(st, 0, xy.y, cols - 1, xy.y); + break; + + default: + /* Ignore */ + break; + } + } + break; + case 'h': + case 'l': + { + bool set = (ch == 'h'); + switch (st->parms[0]) { + case 7: /* DECAWM */ + st->autowrap = set; + break; + case 20: /* LNM */ + st->autocr = set; + break; + case 25: /* DECTECM */ + st->cursor = set; + op->showcursor(st); + break; + default: + /* Ignore */ + break; + } + break; + } + case 'm': + { + static const int ansi2pc[8] = + { 0, 4, 2, 6, 1, 5, 3, 7 }; + + int i; + for (i = 0; i <= st->nparms; i++) { + int a = st->parms[i]; + switch (a) { + case 0: + st->fg = 7; + st->bg = 0; + st->intensity = 1; + st->underline = 0; + st->blink = 0; + st->reverse = 0; + break; + case 1: + st->intensity = 2; + break; + case 2: + st->intensity = 0; + break; + case 4: + st->underline = 1; + break; + case 5: + st->blink = 1; + break; + case 7: + st->reverse = 1; + break; + case 21: + case 22: + st->intensity = 1; + break; + case 24: + st->underline = 0; + break; + case 25: + st->blink = 0; + break; + case 27: + st->reverse = 0; + break; + case 30 ... 37: + st->fg = ansi2pc[a - 30]; + break; + case 38: + st->fg = 7; + st->underline = 1; + break; + case 39: + st->fg = 7; + st->underline = 0; + break; + case 40 ... 47: + st->bg = ansi2pc[a - 40]; + break; + case 49: + st->bg = 7; + break; + default: + /* Do nothing */ + break; + } + } + } + break; + case 's': + st->saved_xy = xy; + break; + case 'u': + xy = st->saved_xy; + break; + default: /* Includes CAN and SUB */ + break; /* Drop unknown sequence */ + } + st->state = st_init; + } + } + break; + + case st_tbl: + st->parms[1] = 0; + if (ch == '#') + st->state = st_tblc; + else + st->state = st_init; + break; + + case st_tblc: + { + unsigned int n = (unsigned char)ch - '0'; + const char *p; + + if (n < 10) { + st->parms[1] = st->parms[1] * 10 + n; + + if (!--st->parms[0]) { + if (st->parms[1] < console_color_table_size) { + /* Set the color table index */ + st->cindex = st->parms[1]; + + /* See if there are any other attributes we care about */ + p = console_color_table[st->parms[1]].ansi; + if (p) { + st->state = st_esc; + __ansi_putchar(ti, '['); + __ansi_putchar(ti, '0'); + __ansi_putchar(ti, ';'); + while (*p) + __ansi_putchar(ti, *p++); + __ansi_putchar(ti, 'm'); + } + } + st->state = st_init; + } + } else { + st->state = st_init; + } + } + break; + } + + /* If we fell off the end of the screen, adjust */ + if (xy.x >= cols) { + if (st->autowrap) { + xy.x = 0; + xy.y++; + } else { + xy.x = cols - 1; + } + } + while (xy.y >= rows) { + xy.y--; + op->scroll_up(st); + } + + /* Update cursor position */ + op->set_cursor(xy.x, xy.y, st->cursor); + st->xy = xy; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/ansi.h b/contrib/syslinux-4.02/com32/lib/sys/ansi.h new file mode 100644 index 0000000..7ccafc8 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/ansi.h @@ -0,0 +1,66 @@ +/* + * ansi.h + */ + +#ifndef COM32_LIB_SYS_ANSI_H +#define COM32_LIB_SYS_ANSI_H + +#include <inttypes.h> +#include <stdbool.h> + +#define ANSI_MAX_PARMS 16 + +enum ansi_state { + st_init, + st_esc, + st_csi, + st_tbl, + st_tblc, +}; + +struct curxy { + uint8_t x, y; +} __attribute__ ((packed)); + +struct term_state { + enum ansi_state state; + int nparms; /* Number of parameters seen */ + int parms[ANSI_MAX_PARMS]; + bool pvt; /* Private code? */ + struct curxy xy; + struct curxy saved_xy; + uint8_t cindex; /* SOH color index */ + uint8_t fg; + uint8_t bg; + uint8_t intensity; + bool vtgraphics; /* VT graphics on/off */ + bool underline; + bool blink; + bool reverse; + bool autocr; + bool autowrap; + bool cursor; +}; + +struct ansi_ops { + void (*erase) (const struct term_state * st, int x0, int y0, int x1, + int y1); + void (*write_char) (int x, int y, uint8_t ch, const struct term_state * st); + void (*showcursor) (const struct term_state * st); + void (*scroll_up) (const struct term_state * st); + void (*set_cursor) (int x, int y, bool visible); + void (*beep) (void); +}; + +struct term_info { + int rows, cols; /* Screen size */ + int disabled; + struct term_state *ts; + const struct ansi_ops *op; +}; + +void __ansi_init(const struct term_info *ti); +void __ansi_putchar(const struct term_info *ti, uint8_t ch); +void __ansicon_beep(void); + +#endif /* COM32_LIB_SYS_ANSI_H */ diff --git a/contrib/syslinux-4.02/com32/lib/sys/ansicon_write.c b/contrib/syslinux-4.02/com32/lib/sys/ansicon_write.c new file mode 100644 index 0000000..b25f2d2 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/ansicon_write.c @@ -0,0 +1,257 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * ansicon_write.c + * + * Write to the screen using ANSI control codes (about as capable as + * DOS' ANSI.SYS.) + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <colortbl.h> +#include <klibc/compiler.h> +#include <syslinux/config.h> +#include "file.h" +#include "ansi.h" + +static void ansicon_erase(const struct term_state *, int, int, int, int); +static void ansicon_write_char(int, int, uint8_t, const struct term_state *); +static void ansicon_showcursor(const struct term_state *); +static void ansicon_scroll_up(const struct term_state *); +static void ansicon_set_cursor(int, int, bool); + +static struct term_state ts; +struct ansi_ops __ansicon_ops = { + .erase = ansicon_erase, + .write_char = ansicon_write_char, + .showcursor = ansicon_showcursor, + .set_cursor = ansicon_set_cursor, + .scroll_up = ansicon_scroll_up, + .beep = __ansicon_beep, +}; + +static struct term_info ti = { + .disabled = 0, + .ts = &ts, + .op = &__ansicon_ops +}; + +#define BIOS_CURXY ((struct curxy *)0x450) /* Array for each page */ +#define BIOS_ROWS (*(uint8_t *)0x484) /* Minus one; if zero use 24 (= 25 lines) */ +#define BIOS_COLS (*(uint16_t *)0x44A) +#define BIOS_PAGE (*(uint8_t *)0x462) + +/* Reference counter to the screen, to keep track of if we need + reinitialization. */ +static int ansicon_counter = 0; + +static uint16_t cursor_type; /* Saved cursor pattern */ + +/* Common setup */ +int __ansicon_open(struct file_info *fp) +{ + static com32sys_t ireg; /* Auto-initalized to all zero */ + com32sys_t oreg; + + if (!ansicon_counter) { + /* Are we disabled? */ + if (syslinux_serial_console_info()->flowctl & 0x8000) { + ti.disabled = 1; + ti.rows = 25; + ti.cols = 80; + } else { + /* Force text mode */ + ireg.eax.w[0] = 0x0005; + __intcall(0x22, &ireg, NULL); + + /* Initial state */ + ti.rows = BIOS_ROWS ? BIOS_ROWS + 1 : 25; + ti.cols = BIOS_COLS; + __ansi_init(&ti); + + /* Get cursor shape and position */ + ireg.eax.b[1] = 0x03; + ireg.ebx.b[1] = BIOS_PAGE; + __intcall(0x10, &ireg, &oreg); + cursor_type = oreg.ecx.w[0]; + ti.ts->xy.x = oreg.edx.b[0]; + ti.ts->xy.y = oreg.edx.b[1]; + } + } + + fp->o.rows = ti.rows; + fp->o.cols = ti.cols; + + ansicon_counter++; + return 0; +} + +int __ansicon_close(struct file_info *fp) +{ + (void)fp; + + ansicon_counter--; + return 0; +} + +/* Turn ANSI attributes into VGA attributes */ +static uint8_t ansicon_attribute(const struct term_state *st) +{ + int bg = st->bg; + int fg; + + if (st->underline) + fg = 0x01; + else if (st->intensity == 0) + fg = 0x08; + else + fg = st->fg; + + if (st->reverse) { + bg = fg & 0x07; + fg &= 0x08; + fg |= st->bg; + } + + if (st->blink) + bg ^= 0x08; + + if (st->intensity == 2) + fg ^= 0x08; + + return (bg << 4) | fg; +} + +/* Erase a region of the screen */ +static void ansicon_erase(const struct term_state *st, + int x0, int y0, int x1, int y1) +{ + static com32sys_t ireg; + + ireg.eax.w[0] = 0x0600; /* Clear window */ + ireg.ebx.b[1] = ansicon_attribute(st); + ireg.ecx.b[0] = x0; + ireg.ecx.b[1] = y0; + ireg.edx.b[0] = x1; + ireg.edx.b[1] = y1; + __intcall(0x10, &ireg, NULL); +} + +/* Show or hide the cursor */ +static void ansicon_showcursor(const struct term_state *st) +{ + static com32sys_t ireg; + + ireg.eax.b[1] = 0x01; + ireg.ecx.w[0] = st->cursor ? cursor_type : 0x2020; + __intcall(0x10, &ireg, NULL); +} + +static void ansicon_set_cursor(int x, int y, bool visible) +{ + const int page = BIOS_PAGE; + struct curxy xy = BIOS_CURXY[page]; + static com32sys_t ireg; + + (void)visible; + + if (xy.x != x || xy.y != y) { + ireg.eax.b[1] = 0x02; + ireg.ebx.b[1] = page; + ireg.edx.b[1] = y; + ireg.edx.b[0] = x; + __intcall(0x10, &ireg, NULL); + } +} + +static void ansicon_write_char(int x, int y, uint8_t ch, + const struct term_state *st) +{ + static com32sys_t ireg; + + ansicon_set_cursor(x, y, false); + + ireg.eax.b[1] = 0x09; + ireg.eax.b[0] = ch; + ireg.ebx.b[1] = BIOS_PAGE; + ireg.ebx.b[0] = ansicon_attribute(st); + ireg.ecx.w[0] = 1; + __intcall(0x10, &ireg, NULL); +} + +static void ansicon_scroll_up(const struct term_state *st) +{ + static com32sys_t ireg; + + ireg.eax.w[0] = 0x0601; + ireg.ebx.b[1] = ansicon_attribute(st); + ireg.ecx.w[0] = 0; + ireg.edx.b[1] = ti.rows - 1; + ireg.edx.b[0] = ti.cols - 1; + __intcall(0x10, &ireg, NULL); /* Scroll */ +} + +ssize_t __ansicon_write(struct file_info *fp, const void *buf, size_t count) +{ + const unsigned char *bufp = buf; + size_t n = 0; + + (void)fp; + + if (ti.disabled) + return count; /* Nothing to do */ + + while (count--) { + __ansi_putchar(&ti, *bufp++); + n++; + } + + return n; +} + +void __ansicon_beep(void) +{ + static com32sys_t ireg; + + ireg.eax.w[0] = 0x0e07; + ireg.ebx.b[1] = BIOS_PAGE; + __intcall(0x10, &ireg, NULL); +} + +const struct output_dev dev_ansicon_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_OUTPUT, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __ansicon_write, + .close = __ansicon_close, + .open = __ansicon_open, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/ansiserial_write.c b/contrib/syslinux-4.02/com32/lib/sys/ansiserial_write.c new file mode 100644 index 0000000..957d1c6 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/ansiserial_write.c @@ -0,0 +1,59 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * ansiserial_write.c + * + * Write to both to the ANSI console and the serial port + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include "file.h" + +extern int __ansicon_open(struct file_info *); +extern int __ansicon_close(struct file_info *); +extern ssize_t __ansicon_write(struct file_info *, const void *, size_t); +extern ssize_t __xserial_write(struct file_info *, const void *, size_t); + +static ssize_t __ansiserial_write(struct file_info *fp, const void *buf, + size_t count) +{ + __ansicon_write(fp, buf, count); + return __xserial_write(fp, buf, count); +} + +const struct output_dev dev_ansiserial_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_OUTPUT, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __ansiserial_write, + .close = __ansicon_close, + .open = __ansicon_open, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/argv.c b/contrib/syslinux-4.02/com32/lib/sys/argv.c new file mode 100644 index 0000000..db287c2 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/argv.c @@ -0,0 +1,97 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * argv.c + * + * Parse a single C string into argc and argv (argc is return value.) + * memptr points to available memory. + */ + +#include <inttypes.h> +#include <stddef.h> +#include <stdio.h> +#include <syslinux/align.h> +#include <com32.h> + +extern char _end[]; /* Symbol created by linker */ +void *__mem_end = &_end; /* Global variable for use by malloc() */ + +int __parse_argv(char ***argv, const char *str) +{ + char dummy_argv0[] = ""; + char *mem = __mem_end; + const char *p = str; + char *q = mem; + char *r; + char **arg; + int wasspace = 1; + int argc = 1; + + /* First copy the string, turning whitespace runs into nulls */ + for (p = str;; p++) { + if (*p <= ' ') { + if (!wasspace) { + wasspace = 1; + *q++ = '\0'; + } + } else { + if (wasspace) { + argc++; + wasspace = 0; + } + *q++ = *p; + } + + /* This test is AFTER we have processed the null byte; + we treat it as a whitespace character so it terminates + the last argument */ + if (!*p) + break; + } + + /* Now create argv */ + arg = (char **)ALIGN_UP_FOR(q, char *); + *argv = arg; + *arg++ = __com32.cs_name ? (char *)__com32.cs_name : dummy_argv0; /* argv[0] */ + + q--; /* Point q to final null */ + if (mem < q) + *arg++ = mem; /* argv[1] */ + + for (r = mem; r < q; r++) { + if (*r == '\0') { + *arg++ = r + 1; + } + } + + *arg++ = NULL; /* Null pointer at the end */ + __mem_end = arg; /* End of memory we used */ + + return argc; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/cfarcall.c b/contrib/syslinux-4.02/com32/lib/sys/cfarcall.c new file mode 100644 index 0000000..fca818b --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/cfarcall.c @@ -0,0 +1,10 @@ +/* + * cfarcall.c + */ + +#include <com32.h> + +int __cfarcall(uint16_t cs, uint16_t ip, const void *stack, uint32_t stack_size) +{ + return __com32.cs_cfarcall((cs << 16) + ip, stack, stack_size); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/close.c b/contrib/syslinux-4.02/com32/lib/sys/close.c new file mode 100644 index 0000000..50d9a42 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/close.c @@ -0,0 +1,62 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * close.c + */ + +#include <errno.h> +#include <com32.h> +#include <string.h> +#include "file.h" + +int close(int fd) +{ + struct file_info *fp = &__file_info[fd]; + int rv = 0; + + if (fd >= NFILES || !fp->iop || !fp->oop) { + errno = EBADF; + return -1; + } + + if (fp->iop->close) { + rv = fp->iop->close(fp); + if (rv) + return rv; + } + fp->iop = &dev_error_r; + + if (fp->oop->close) { + rv = fp->oop->close(fp); + if (rv) + return rv; + } + + memset(fp, 0, sizeof *fp); /* File structure unused */ + return 0; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/colortable.c b/contrib/syslinux-4.02/com32/lib/sys/colortable.c new file mode 100644 index 0000000..ab1c424 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/colortable.c @@ -0,0 +1,9 @@ +#include <colortbl.h> + +static struct color_table default_color_table[] = { + {"default", "0", 0xffffffff, 0x00000000, SHADOW_NORMAL} +}; + +struct color_table *console_color_table = default_color_table; +int console_color_table_size = + (sizeof default_color_table / sizeof(struct color_table)); diff --git a/contrib/syslinux-4.02/com32/lib/sys/entry.S b/contrib/syslinux-4.02/com32/lib/sys/entry.S new file mode 100644 index 0000000..7bfde8b --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/entry.S @@ -0,0 +1,118 @@ +/* ----------------------------------------------------------------------- + * + * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * COM32 start up code - must be linked first in the binary + */ + +/* Number of arguments in our version of the entry structure */ +#define COM32_ARGS 9 + + .section ".init","ax" + .globl _start + .type _start, @function +_start: + /* This first instruction acts as COM32R magic number */ + movl $0x21cd4cfe,%eax + + /* Upwards string operations */ + cld + + /* Find our own location */ + call 1f +1: popl %ebx + addl $_GLOBAL_OFFSET_TABLE_ + (. - 1b), %ebx + + /* Process relocations (which overlay the .bss segment) */ + leal _edata@GOTOFF(%ebx),%esi + leal _start@GOTOFF(%ebx),%edx +2: lodsl + andl %eax,%eax + jz 3f + addl %edx,(%eax,%edx) + jmp 2b +3: + /* Relocate the GOT (is this right?) */ + leal __got_start@GOTOFF(%ebx),%esi + leal __got_end@GOTOFF(%ebx),%edi +4: + addl %edx,(%esi) + addl $4,%esi + cmpl %edi,%esi + jb 4b + + /* Zero the .bss segment */ + xorl %eax,%eax + leal __bss_start@GOTOFF(%ebx),%edi + leal _end+3@GOTOFF(%ebx),%ecx + subl %edi,%ecx + shrl $2,%ecx + rep ; stosl + + /* Copy COM32 invocation parameters */ + leal 4(%esp),%esi # Argument list + leal __com32@GOTOFF(%ebx),%edi + movl $(COM32_ARGS),%ecx + movl %esp,-4(%edi) # Save the initial stack ptr + cmpl (%esi),%ecx + jbe 5f + movl (%esi),%ecx +5: inc %ecx # Copy the argument count, too + rep ; movsl + + /* Parse the command line (assumes REGPARM) */ + movl __com32+4@GOTOFF(%ebx),%edx # Command line + pushl %edx # Make space for argv + movl %esp,%eax + call __parse_argv + pushl %eax # Save argc + + /* Look for library initialization functions */ + leal __ctors_start@GOTOFF(%ebx),%esi + leal __ctors_end@GOTOFF(%ebx),%edi +6: + cmpl %edi,%esi + jae 7f + call *(%esi) + addl $4,%esi + jmp 6b +/* + * Actually run main. This assumes REGPARM is used!!!! + */ +7: + popl %eax # argc + popl %edx # argv + call main + call *__exit_handler@GOTOFF(%ebx) + hlt + .size _start, .-_start + + .bss + .globl __entry_esp +__entry_esp: .space 4 + .globl __com32 +__com32: .space 4*(COM32_ARGS+1) diff --git a/contrib/syslinux-4.02/com32/lib/sys/err_read.c b/contrib/syslinux-4.02/com32/lib/sys/err_read.c new file mode 100644 index 0000000..22555ca --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/err_read.c @@ -0,0 +1,55 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * err_read.c + * + * Reading from a device which doesn't support reading + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include "file.h" + +static ssize_t __err_read(struct file_info *fp, void *buf, size_t count) +{ + (void)fp; + (void)buf; + (void)count; + errno = -EINVAL; + return -1; +} + +const struct input_dev dev_error_r = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_INPUT | __DEV_ERROR, + .fileflags = O_RDONLY, + .read = __err_read, + .close = NULL, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/err_write.c b/contrib/syslinux-4.02/com32/lib/sys/err_write.c new file mode 100644 index 0000000..fab60ba --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/err_write.c @@ -0,0 +1,55 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * err_write.c + * + * Writing to a device which doesn't support writing + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include "file.h" + +static ssize_t __err_write(struct file_info *fp, const void *buf, size_t count) +{ + (void)fp; + (void)buf; + (void)count; + errno = -EINVAL; + return -1; +} + +const struct output_dev dev_error_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_OUTPUT | __DEV_ERROR, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __err_write, + .close = NULL, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/exit.S b/contrib/syslinux-4.02/com32/lib/sys/exit.S new file mode 100644 index 0000000..2ab8012 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/exit.S @@ -0,0 +1,41 @@ +/* + * Implementation of _exit() for com32 based on c32entry.S + */ + .text + + .globl _Exit + .type _Exit, @function +_Exit: + /* Just fall through to _exit */ + .size _Exit, .-_Exit + + .globl _exit + .type _exit, @function +_exit: +#ifdef REGPARM + pushl %eax +#endif + + /* Run any destructors */ + movl $__dtors_start, %esi +2: + cmpl $__dtors_end, %esi + jae 1f + call *(%esi) + addl $4,%esi + jmp 2b + +1: +#ifdef REGPARM + popl %eax +#else + movl 4(%esp),%eax # Exit code in %eax = return value +#endif + movl (__entry_esp),%esp # Return stack pointer to entry value + ret # Return to termination address + .size _exit, .-_exit + + .data +__exit_handler: + .globl __exit_handler + .long _exit diff --git a/contrib/syslinux-4.02/com32/lib/sys/farcall.c b/contrib/syslinux-4.02/com32/lib/sys/farcall.c new file mode 100644 index 0000000..988ee6d --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/farcall.c @@ -0,0 +1,24 @@ +/* + * farcall.c + */ + +#include <com32.h> + +static inline uint32_t eflags(void) +{ + uint32_t v; + + asm volatile("pushfl ; popl %0" : "=rm" (v)); + return v; +} + +void __farcall(uint16_t cs, uint16_t ip, + const com32sys_t * ireg, com32sys_t * oreg) +{ + com32sys_t xreg = *ireg; + + /* Enable interrupts if and only if they are enabled in the caller */ + xreg.eflags.l = (xreg.eflags.l & ~EFLAGS_IF) | (eflags() & EFLAGS_IF); + + __com32.cs_farcall((cs << 16) + ip, &xreg, oreg); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/file.h b/contrib/syslinux-4.02/com32/lib/sys/file.h new file mode 100644 index 0000000..e984f16 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/file.h @@ -0,0 +1,106 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * file.h + * + * Internal implementation of file I/O for COM32 + */ + +#ifndef _COM32_SYS_FILE_H +#define _COM32_SYS_FILE_H + +#include <inttypes.h> +#include <stdlib.h> +#include <sys/types.h> +#include <dev.h> +#include <fcntl.h> +#include <syslinux/pmapi.h> + +/* Device structure; contains the relevant operations */ + +struct file_info; + +#define __DEV_MAGIC 0xf4e7 +#define __DEV_TTY 0x0001 /* TTY - must be bit 0 */ +#define __DEV_FILE 0x0002 /* Ordinary file */ +#define __DEV_OUTPUT 0x0004 /* This is an output device */ +#define __DEV_INPUT 0 /* Dummy */ +#define __DEV_ERROR 0x0008 /* This is the error device */ +#define __DEV_NULL 0x0010 /* This is the null device */ + +struct input_dev { + uint16_t dev_magic; /* Magic number */ + uint16_t flags; /* Flags */ + int fileflags; /* Permitted file flags */ + ssize_t (*read)(struct file_info *, void *, size_t); + int (*close)(struct file_info *); + int (*open)(struct file_info *); +}; + +struct output_dev { + uint16_t dev_magic; /* Magic number */ + uint16_t flags; /* Flags */ + int fileflags; + ssize_t (*write)(struct file_info *, const void *, size_t); + int (*close)(struct file_info *); + int (*open)(struct file_info *); + const struct output_dev *fallback; /* Fallback option for certain consoles */ +}; + +/* File structure */ + +#define NFILES 32 /* Number of files to support */ +#define MAXBLOCK 16384 /* Defined by ABI */ + +struct file_info { + const struct input_dev *iop; /* Input operations */ + const struct output_dev *oop; /* Output operations */ + + /* Output file data */ + struct { + int rows, cols; /* Rows and columns */ + } o; + + /* Structure used for input blocking */ + struct { + struct com32_filedata fd; + size_t offset; /* Current file offset */ + size_t nbytes; /* Number of bytes available in buffer */ + char *datap; /* Current data pointer */ + void *pvt; /* Private pointer for driver */ + char buf[MAXBLOCK]; + } i; +}; + +extern struct file_info __file_info[NFILES]; + +/* Line input discipline */ +ssize_t __line_input(struct file_info *fp, char *buf, size_t bufsize, + ssize_t(*get_char) (struct file_info *, void *, size_t)); + +#endif /* _COM32_SYS_FILE_H */ diff --git a/contrib/syslinux-4.02/com32/lib/sys/fileclose.c b/contrib/syslinux-4.02/com32/lib/sys/fileclose.c new file mode 100644 index 0000000..e2c929f --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/fileclose.c @@ -0,0 +1,45 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * fileclose.c + * + * Close an ordinary file + */ + +#include <errno.h> +#include <com32.h> +#include <string.h> +#include "file.h" + +int __file_close(struct file_info *fp) +{ + if (fp->i.fd.handle) + __com32.cs_pm->close_file(fp->i.fd.handle); + + return 0; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/fileinfo.c b/contrib/syslinux-4.02/com32/lib/sys/fileinfo.c new file mode 100644 index 0000000..a1fc7c9 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/fileinfo.c @@ -0,0 +1,3 @@ +#include "file.h" + +struct file_info __file_info[NFILES]; diff --git a/contrib/syslinux-4.02/com32/lib/sys/fileread.c b/contrib/syslinux-4.02/com32/lib/sys/fileread.c new file mode 100644 index 0000000..aab99c8 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/fileread.c @@ -0,0 +1,98 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * read.c + * + * Reading from a file + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <syslinux/pmapi.h> +#include <minmax.h> +#include "file.h" + +int __file_get_block(struct file_info *fp) +{ + ssize_t bytes_read; + + bytes_read = __com32.cs_pm->read_file(&fp->i.fd.handle, fp->i.buf, + MAXBLOCK >> fp->i.fd.blocklg2); + if (!bytes_read) { + errno = EIO; + return -1; + } + + fp->i.nbytes = bytes_read; + fp->i.datap = fp->i.buf; + return 0; +} + +ssize_t __file_read(struct file_info * fp, void *buf, size_t count) +{ + char *bufp = buf; + ssize_t n = 0; + size_t ncopy; + + while (count) { + if (fp->i.nbytes == 0) { + if (fp->i.offset >= fp->i.fd.size || !fp->i.fd.handle) + return n; /* As good as it gets... */ + + if (count > MAXBLOCK) { + /* Large transfer: copy directly, without buffering */ + ncopy = __com32.cs_pm->read_file(&fp->i.fd.handle, bufp, + count >> fp->i.fd.blocklg2); + if (!ncopy) { + errno = EIO; + return n ? n : -1; + } + + goto got_data; + } else { + if (__file_get_block(fp)) + return n ? n : -1; + } + } + + ncopy = min(count, fp->i.nbytes); + memcpy(bufp, fp->i.datap, ncopy); + + fp->i.datap += ncopy; + fp->i.offset += ncopy; + fp->i.nbytes -= ncopy; + + got_data: + n += ncopy; + bufp += ncopy; + count -= ncopy; + } + + return n; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/fstat.c b/contrib/syslinux-4.02/com32/lib/sys/fstat.c new file mode 100644 index 0000000..0ce8cad --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/fstat.c @@ -0,0 +1,63 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2005-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * fstat.c + * + * Very trivial fstat emulation + */ + +#include <sys/stat.h> +#include <errno.h> +#include "file.h" + +int fstat(int fd, struct stat *buf) +{ + struct file_info *fp = &__file_info[fd]; + + if (fd >= NFILES || !fp->iop) { + errno = EBADF; + return -1; + } + + if (fp->iop->flags & __DEV_FILE) { + if (fp->i.fd.size == (uint32_t) - 1) { + /* File of unknown length, report it as a socket + (it probably really is, anyway!) */ + buf->st_mode = S_IFSOCK | 0444; + buf->st_size = 0; + } else { + buf->st_mode = S_IFREG | 0444; + buf->st_size = fp->i.fd.size; + } + } else { + buf->st_mode = S_IFCHR | 0666; + buf->st_size = 0; + } + + return 0; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/ftell.c b/contrib/syslinux-4.02/com32/lib/sys/ftell.c new file mode 100644 index 0000000..5c1a944 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/ftell.c @@ -0,0 +1,16 @@ +/* + * sys/ftell.c + * + * We can't seek, but we can at least tell... + */ + +#include <stdio.h> +#include "sys/file.h" + +long ftell(FILE * stream) +{ + int fd = fileno(stream); + struct file_info *fp = &__file_info[fd]; + + return fp->i.offset; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/gpxe.c b/contrib/syslinux-4.02/com32/lib/sys/gpxe.c new file mode 100644 index 0000000..d86da42 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/gpxe.c @@ -0,0 +1,50 @@ +#include <sys/gpxe.h> +#include <syslinux/config.h> +#include <string.h> + +bool is_gpxe(void) +{ + const struct syslinux_version *sv; + com32sys_t reg; + struct s_PXENV_FILE_CHECK_API *fca; + bool gpxe; + + sv = syslinux_version(); + if (sv->filesystem != SYSLINUX_FS_PXELINUX) + return false; /* Not PXELINUX */ + + fca = lzalloc(sizeof *fca); + if (!fca) + return false; + fca->Size = sizeof *fca; + fca->Magic = 0x91d447b2; + + memset(®, 0, sizeof reg); + reg.eax.w[0] = 0x0009; + reg.ebx.w[0] = 0x00e6; /* PXENV_FILE_API_CHECK */ + /* reg.edi.w[0] = OFFS(fca); */ + reg.es = SEG(fca); + + __intcall(0x22, ®, ®); + + gpxe = true; + + if (reg.eflags.l & EFLAGS_CF) + gpxe = false; /* Cannot invoke PXE stack */ + + if (reg.eax.w[0] || fca->Status) + gpxe = false; /* PXE failure */ + + if (fca->Magic != 0xe9c17b20) + gpxe = false; /* Incorrect magic */ + + if (fca->Size < sizeof *fca) + gpxe = false; /* Short return */ + + /* XXX: The APIs to test for should be a passed-in option */ + if (!(fca->APIMask & (1 << 5))) + gpxe = false; /* No FILE EXEC */ + + lfree(fca); + return gpxe; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/intcall.c b/contrib/syslinux-4.02/com32/lib/sys/intcall.c new file mode 100644 index 0000000..e97a384 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/intcall.c @@ -0,0 +1,10 @@ +/* + * intcall.c + */ + +#include <com32.h> + +void __intcall(uint8_t vector, const com32sys_t * ireg, com32sys_t * oreg) +{ + __com32.cs_intcall(vector, ireg, oreg); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/isatty.c b/contrib/syslinux-4.02/com32/lib/sys/isatty.c new file mode 100644 index 0000000..d80214a --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/isatty.c @@ -0,0 +1,53 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * isatty.c + * + * Return if this is a tty or not + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <unistd.h> +#include <klibc/compiler.h> +#include "file.h" + +int isatty(int fd) +{ + struct file_info *fp = &__file_info[fd]; + + if (fd >= NFILES || !fp->iop) { + errno = EBADF; + return -1; + } + + /* __DEV_TTY == 1 */ + return (fp->iop->flags & __DEV_TTY); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/libansi.c b/contrib/syslinux-4.02/com32/lib/sys/libansi.c new file mode 100644 index 0000000..a011cb8 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/libansi.c @@ -0,0 +1,247 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2009 Erwan Velu - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- + * Ansi Sequences can be found here : + * http://ascii-table.com/ansi-escape-sequences-vt-100.php + * http://en.wikipedia.org/wiki/ANSI_escape_code + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdbool.h> +#include <stdint.h> + +#include "libansi.h" + +void display_cursor(bool status) +{ + if (status == true) { + fputs(CSI "?25h", stdout); + } else { + fputs(CSI "?25l", stdout); + } +} + +void clear_end_of_line(void) +{ + fputs(CSI "0K", stdout); +} + +void move_cursor_left(int count) +{ + char buffer[10]; + memset(buffer,0,sizeof(buffer)); + sprintf(buffer,CSI "%dD",count); + fputs(buffer, stdout); +} + +void move_cursor_right(int count) +{ + char buffer[10]; + memset(buffer,0,sizeof(buffer)); + sprintf(buffer, CSI "%dC", count); + fputs(buffer, stdout); +} + +void set_cursor_blink(bool status) { + if (status == true) + fputs("\033[05m",stdout); + else + fputs("\033[0m",stdout); +} + +void clear_line(void) +{ + fputs(CSI "2K", stdout); +} + +void clear_beginning_of_line(void) +{ + fputs(CSI "1K", stdout); +} + +void move_cursor_to_column(int count) +{ + char buffer[10]; + memset(buffer,0,sizeof(buffer)); + sprintf(buffer, CSI "%dG", count); + fputs(buffer, stdout); +} + +void move_cursor_to_next_line(void) +{ + fputs("\033e", stdout); +} + +void disable_utf8(void) +{ + fputs("\033%@", stdout); +} + +void set_g1_special_char(void){ + fputs("\033)0", stdout); +} + +void set_us_g0_charset(void) +{ + fputs("\033(B\1#0", stdout); +} + +void clear_entire_screen(void) +{ + fputs(CSI "2J", stdout); +} + +/** + * cprint_vga2ansi - given a VGA attribute, print a character + * @chr: character to print + * @attr: vga attribute + * + * Convert the VGA attribute @attr to an ANSI escape sequence and + * print it. + * For performance, SGR parameters are cached. To reset them, + * call cprint_vga2ansi('0', '0'). + **/ +static void cprint_vga2ansi(const char chr, const char attr) +{ + static const char ansi_char[8] = "04261537"; + static uint16_t last_attr = 0x300; + char buf[16], *p; + + if (chr == '0' && attr == '0') { + last_attr = 0x300; + return; + } + + if (attr != last_attr) { + bool reset = false; + p = buf; + *p++ = '\033'; + *p++ = '['; + + if (last_attr & ~attr & 0x88) { + *p++ = '0'; + *p++ = ';'; + /* Reset last_attr to unknown to handle + * background/foreground attributes correctly */ + last_attr = 0x300; + reset = true; + } + if (attr & 0x08) { + *p++ = '1'; + *p++ = ';'; + } + if (attr & 0x80) { + *p++ = '4'; + *p++ = ';'; + } + if (reset || (attr ^ last_attr) & 0x07) { + *p++ = '3'; + *p++ = ansi_char[attr & 7]; + *p++ = ';'; + } + if (reset || (attr ^ last_attr) & 0x70) { + *p++ = '4'; + *p++ = ansi_char[(attr >> 4) & 7]; + *p++ = ';'; + } + p[-1] = 'm'; /* We'll have generated at least one semicolon */ + p[0] = '\0'; + + last_attr = attr; + + fputs(buf, stdout); + } + + putchar(chr); +} + +/* + * cls - clear and initialize the entire screen + * + * Note: when initializing xterm, one has to specify that + * G1 points to the alternate character set (this is not true + * by default). Without the initial printf "\033)0", line drawing + * characters won't be displayed. + */ +void cls(void) +{ + fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout); + + /* Reset SGR parameters cache */ + cprint_vga2ansi('0', '0'); +} + +void reset_colors(void) +{ + csprint(CSI "1D", 0x07); +} + +/** + * cprint - given a VGA attribute, print a single character at cursor + * @chr: character to print + * @attr: VGA attribute + * @times: number of times to print @chr + * + * Note: @attr is a VGA attribute. + **/ +void cprint(const char chr, const char attr, unsigned int times) +{ + while (times--) + cprint_vga2ansi(chr, attr); +} + +/** + * csprint - given a VGA attribute, print a NULL-terminated string + * @str: string to print + * @attr: VGA attribute + **/ +void csprint(const char *str, const char attr) +{ + while (*str) { + cprint(*str, attr, 1); + str++; + } +} + +/** + * clearwindow - fill a given a region on the screen + * @top, @left, @bot, @right: coordinates to fill + * @fillchar: character to use to fill the region + * @fillattr: character attribute (VGA) + **/ +void clearwindow(const char top, const char left, const char bot, + const char right, const char fillchar, const char fillattr) +{ + char x; + for (x = top; x < bot + 1; x++) { + gotoxy(x, left); + cprint(fillchar, fillattr, right - left + 1); + } +} + + diff --git a/contrib/syslinux-4.02/com32/lib/sys/line_input.c b/contrib/syslinux-4.02/com32/lib/sys/line_input.c new file mode 100644 index 0000000..a8c9926 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/line_input.c @@ -0,0 +1,90 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * line_input.c + * + * Line-oriented input discupline + */ + +#include "file.h" +#include <errno.h> +#include <syslinux/idle.h> + +ssize_t __line_input(struct file_info * fp, char *buf, size_t bufsize, + ssize_t(*get_char) (struct file_info *, void *, size_t)) +{ + size_t n = 0; + char ch; + int rv; + ssize_t(*const Write) (struct file_info *, const void *, size_t) = + fp->oop->write; + + for (;;) { + rv = get_char(fp, &ch, 1); + + if (rv != 1) { + syslinux_idle(); + continue; + } + + switch (ch) { + case '\n': /* Ignore incoming linefeed */ + break; + + case '\r': + *buf = '\n'; + Write(fp, "\n", 1); + return n + 1; + + case '\b': + if (n > 0) { + n--; + buf--; + Write(fp, "\b \b", 3); + } + break; + + case '\x15': /* Ctrl-U */ + while (n) { + n--; + buf--; + Write(fp, "\b \b", 3); + } + break; + + default: + if (n < bufsize - 1) { + *buf = ch; + Write(fp, buf, 1); + n++; + buf++; + } + break; + } + } +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/null_read.c b/contrib/syslinux-4.02/com32/lib/sys/null_read.c new file mode 100644 index 0000000..e0037c5 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/null_read.c @@ -0,0 +1,54 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * null_read.c + * + * Reading null device + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include "file.h" + +static ssize_t __null_read(struct file_info *fp, void *buf, size_t count) +{ + (void)fp; + (void)buf; + (void)count; + return 0; +} + +const struct input_dev dev_null_r = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_INPUT | __DEV_NULL, + .fileflags = O_RDONLY, + .read = __null_read, + .close = NULL, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/null_write.c b/contrib/syslinux-4.02/com32/lib/sys/null_write.c new file mode 100644 index 0000000..a29b213 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/null_write.c @@ -0,0 +1,54 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * null_write.c + * + * Null writing device + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include "file.h" + +static ssize_t __null_write(struct file_info *fp, const void *buf, size_t count) +{ + (void)fp; + (void)buf; + (void)count; + return count; +} + +const struct output_dev dev_null_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_OUTPUT | __DEV_NULL, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __null_write, + .close = NULL, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/open.c b/contrib/syslinux-4.02/com32/lib/sys/open.c new file mode 100644 index 0000000..cb7c1b4 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/open.c @@ -0,0 +1,73 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <errno.h> +#include <com32.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include "file.h" + +/* + * open.c + * + * Open an ordinary file + */ + +extern ssize_t __file_read(struct file_info *, void *, size_t); +extern int __file_close(struct file_info *); + +const struct input_dev __file_dev = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_FILE | __DEV_INPUT, + .fileflags = O_RDONLY, + .read = __file_read, + .close = __file_close, + .open = NULL, +}; + +int open(const char *pathname, int flags, ...) +{ + int fd, handle; + struct file_info *fp; + + fd = opendev(&__file_dev, NULL, flags); + + if (fd < 0) + return -1; + + fp = &__file_info[fd]; + + handle = __com32.cs_pm->open_file(pathname, &fp->i.fd); + if (handle < 0) + return -1; + + fp->i.offset = 0; + fp->i.nbytes = 0; + + return fd; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/openconsole.c b/contrib/syslinux-4.02/com32/lib/sys/openconsole.c new file mode 100644 index 0000000..3c7567b --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/openconsole.c @@ -0,0 +1,51 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * openconsole.c + * + * Open the chosen console device + */ + +#include <unistd.h> +#include <console.h> +#include <fcntl.h> + +int openconsole(const struct input_dev *idev, const struct output_dev *odev) +{ + close(0); + if (opendev(idev, odev, O_RDONLY) != 0) + return -1; + close(1); + if (opendev(idev, odev, O_WRONLY) != 1) + return -1; + close(2); + if (opendev(idev, odev, O_WRONLY) != 2) + return -1; + + return 0; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/opendev.c b/contrib/syslinux-4.02/com32/lib/sys/opendev.c new file mode 100644 index 0000000..1df9d07 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/opendev.c @@ -0,0 +1,99 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <errno.h> +#include <com32.h> +#include <string.h> +#include <unistd.h> +#include "file.h" + +/* + * opendev.c + * + * Open a special device + */ + +int opendev(const struct input_dev *idev, + const struct output_dev *odev, int flags) +{ + int fd; + struct file_info *fp; + int okflags; + int e; + + okflags = (idev ? idev->fileflags : 0) | (odev ? odev->fileflags : 0); + + if (!(flags & 3) || (flags & ~okflags)) { + errno = EINVAL; + return -1; + } + + for (fd = 0, fp = __file_info; fd < NFILES; fd++, fp++) + if (!fp->iop && !fp->oop) + break; + + if (fd >= NFILES) { + errno = EMFILE; + return -1; + } + + /* The file structure is already zeroed */ + fp->iop = &dev_error_r; + fp->oop = &dev_error_w; + fp->i.datap = fp->i.buf; + + if (idev) { + if (idev->open && (e = idev->open(fp))) { + errno = e; + goto puke; + } + fp->iop = idev; + } + + while (odev) { + if (odev->open && (e = odev->open(fp))) { + if (e == EAGAIN) { + if (odev->fallback) { + odev = odev->fallback; + continue; + } else { + e = EIO; + } + } + errno = e; + goto puke; + } + fp->oop = odev; + break; + } + + return fd; + +puke: + close(fd); + return -1; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/openmem.c b/contrib/syslinux-4.02/com32/lib/sys/openmem.c new file mode 100644 index 0000000..a56a4af --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/openmem.c @@ -0,0 +1,61 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <errno.h> +#include <com32.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include "file.h" + +/* + * openmem.c + * + * Open a chunk of memory as if it was a file + */ + +const struct input_dev __file_dev; + +int openmem(const void *base, size_t len, int flags) +{ + int fd; + struct file_info *fp; + + fd = opendev(&__file_dev, NULL, flags); + + if (fd < 0) + return -1; + + fp = &__file_info[fd]; + + fp->i.fd.size = fp->i.nbytes = len; + fp->i.datap = (void *)base; + fp->i.fd.handle = 0; /* No actual file */ + fp->i.offset = 0; + + return fd; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/rawcon_read.c b/contrib/syslinux-4.02/com32/lib/sys/rawcon_read.c new file mode 100644 index 0000000..92c9b29 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/rawcon_read.c @@ -0,0 +1,80 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * rawcon_read.c + * + * Character-oriented reading from the console without echo; + * this is a NONBLOCKING device. + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <sys/times.h> +#include "file.h" + +/* Global, since it's used by stdcon_read */ +ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count) +{ + com32sys_t ireg, oreg; + char *bufp = buf; + size_t n = 0; + clock_t start; + + (void)fp; + + memset(&ireg, 0, sizeof ireg); + + start = times(NULL); + + while (n < count) { + /* Poll */ + ireg.eax.b[1] = 0x0B; + __intcall(0x21, &ireg, &oreg); + if (!oreg.eax.b[0]) + break; + + /* We have data, go get it */ + ireg.eax.b[1] = 0x08; + __intcall(0x21, &ireg, &oreg); + *bufp++ = oreg.eax.b[0]; + n++; + } + + return n; +} + +const struct input_dev dev_rawcon_r = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_INPUT, + .fileflags = O_RDONLY, + .read = __rawcon_read, + .close = NULL, + .open = NULL, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/rawcon_write.c b/contrib/syslinux-4.02/com32/lib/sys/rawcon_write.c new file mode 100644 index 0000000..2d45a7b --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/rawcon_write.c @@ -0,0 +1,67 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * rawcon_write.c + * + * Raw writing to the console; no \n -> \r\n translation + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include "file.h" + +static ssize_t __rawcon_write(struct file_info *fp, const void *buf, + size_t count) +{ + com32sys_t ireg; + const char *bufp = buf; + size_t n = 0; + + (void)fp; + + memset(&ireg, 0, sizeof ireg); + ireg.eax.b[1] = 0x02; + + while (count--) { + ireg.edx.b[0] = *bufp++; + __intcall(0x21, &ireg, NULL); + n++; + } + + return n; +} + +const struct output_dev dev_rawcon_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_OUTPUT, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __rawcon_write, + .close = NULL, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/read.c b/contrib/syslinux-4.02/com32/lib/sys/read.c new file mode 100644 index 0000000..e097ade --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/read.c @@ -0,0 +1,51 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * read.c + * + * Reading from a file descriptor + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <klibc/compiler.h> +#include "file.h" + +ssize_t read(int fd, void *buf, size_t count) +{ + struct file_info *fp = &__file_info[fd]; + + if (fd >= NFILES || !fp->iop) { + errno = EBADF; + return -1; + } + + return fp->iop->read(fp, buf, count); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/readdir.c b/contrib/syslinux-4.02/com32/lib/sys/readdir.c new file mode 100644 index 0000000..d2a8c03 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/readdir.c @@ -0,0 +1,30 @@ +/* + * readdir.c + */ + +#include <dirent.h> +#include <stdio.h> +#include <errno.h> + +#include <com32.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> + +#include <syslinux/pmapi.h> + +DIR *opendir(const char *pathname) +{ + return __com32.cs_pm->opendir(pathname); +} + +struct dirent *readdir(DIR *dir) +{ + return __com32.cs_pm->readdir(dir); +} + +int closedir(DIR *dir) +{ + return __com32.cs_pm->closedir(dir); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/screensize.c b/contrib/syslinux-4.02/com32/lib/sys/screensize.c new file mode 100644 index 0000000..340227c --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/screensize.c @@ -0,0 +1,23 @@ +#include <unistd.h> +#include <errno.h> +#include "file.h" + +int getscreensize(int fd, int *rows, int *cols) +{ + struct file_info *fp = &__file_info[fd]; + + if (fd >= NFILES || !fp->iop) { + errno = EBADF; + return -1; + } + + *rows = fp->o.rows; + *cols = fp->o.cols; + + if (!rows || !cols) { + errno = ENOTTY; + return -1; + } + + return 0; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/serial_write.c b/contrib/syslinux-4.02/com32/lib/sys/serial_write.c new file mode 100644 index 0000000..fa0f4f4 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/serial_write.c @@ -0,0 +1,71 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * serial_write.c + * + * Raw writing to the serial port; no \n -> \r\n translation + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <syslinux/config.h> +#include "file.h" + +ssize_t __serial_write(struct file_info *fp, const void *buf, size_t count) +{ + com32sys_t ireg; + const char *bufp = buf; + size_t n = 0; + + (void)fp; + + if (!syslinux_serial_console_info()->iobase) + return count; /* Nothing to do */ + + memset(&ireg, 0, sizeof ireg); + ireg.eax.b[1] = 0x04; + + while (count--) { + ireg.edx.b[0] = *bufp++; + __intcall(0x21, &ireg, NULL); + n++; + } + + return n; +} + +const struct output_dev dev_serial_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_OUTPUT, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __serial_write, + .close = NULL, + .open = NULL, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/sleep.c b/contrib/syslinux-4.02/com32/lib/sys/sleep.c new file mode 100644 index 0000000..8a51c1c --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/sleep.c @@ -0,0 +1,22 @@ +/* + * sys/sleep.c + */ + +#include <unistd.h> +#include <sys/times.h> +#include <syslinux/idle.h> + +unsigned int msleep(unsigned int msec) +{ + clock_t start = times(NULL); + + while (times(NULL) - start < msec) + syslinux_idle(); + + return 0; +} + +unsigned int sleep(unsigned int seconds) +{ + return msleep(seconds * 1000); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/stdcon_read.c b/contrib/syslinux-4.02/com32/lib/sys/stdcon_read.c new file mode 100644 index 0000000..967e564 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/stdcon_read.c @@ -0,0 +1,76 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * stdcon_read.c + * + * Line-oriented reading from the standard console + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include "file.h" + +extern ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count); + +static ssize_t __stdcon_read(struct file_info *fp, void *buf, size_t count) +{ + char *bufp = buf; + size_t n = 0; + char ch; + + (void)fp; + + while (n < count) { + if (fp->i.nbytes) { + ch = *bufp++ = *fp->i.datap++; + fp->i.nbytes--; + n++; + if (ch == '\n') + return n; + } else { + fp->i.nbytes = __line_input(fp, fp->i.buf, MAXBLOCK, __rawcon_read); + fp->i.datap = fp->i.buf; + + if (fp->i.nbytes == 0) + return n; + } + } + + return n; +} + +const struct input_dev dev_stdcon_r = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_INPUT, + .fileflags = O_RDONLY, + .read = __stdcon_read, + .close = NULL, + .open = NULL, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/stdcon_write.c b/contrib/syslinux-4.02/com32/lib/sys/stdcon_write.c new file mode 100644 index 0000000..9cb2f7d --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/stdcon_write.c @@ -0,0 +1,89 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * stdcon_write.c + * + * Writing to the console; \n -> \r\n conversion. + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include "file.h" + +#define BIOS_ROWS (*(uint8_t *)0x484) /* Minus one; if zero use 24 (= 25 lines) */ +#define BIOS_COLS (*(uint16_t *)0x44A) + +static int __stdcon_open(struct file_info *fp) +{ + fp->o.rows = BIOS_ROWS + 1; + fp->o.cols = BIOS_COLS; + + /* Sanity check */ + if (fp->o.rows < 12) + fp->o.rows = 24; + if (fp->o.cols < 40) + fp->o.cols = 80; + + return 0; +} + +static ssize_t __stdcon_write(struct file_info *fp, const void *buf, + size_t count) +{ + com32sys_t ireg; + const char *bufp = buf; + size_t n = 0; + + (void)fp; + + memset(&ireg, 0, sizeof ireg); + ireg.eax.b[1] = 0x02; + + while (count--) { + if (*bufp == '\n') { + ireg.edx.b[0] = '\r'; + __intcall(0x21, &ireg, NULL); + } + ireg.edx.b[0] = *bufp++; + __intcall(0x21, &ireg, NULL); + n++; + } + + return n; +} + +const struct output_dev dev_stdcon_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_OUTPUT, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __stdcon_write, + .close = NULL, + .open = __stdcon_open, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/times.c b/contrib/syslinux-4.02/com32/lib/sys/times.c new file mode 100644 index 0000000..dd063f3 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/times.c @@ -0,0 +1,42 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * sys/times.c + * + * Returns something like a clock. + */ + +#include <sys/times.h> +#include <syslinux/pmapi.h> +#include <com32.h> + +clock_t times(struct tms * buf) +{ + (void)buf; + return *__com32.cs_pm->ms_timer; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/alphatbl.pl b/contrib/syslinux-4.02/com32/lib/sys/vesa/alphatbl.pl new file mode 100644 index 0000000..d70c76e --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/alphatbl.pl @@ -0,0 +1,53 @@ +#!/usr/bin/perl +# +# Produce gamma-correction tables for alpha blending, assuming sRGB space. +# + +sub srgb_to_linear($) +{ + my($s) = @_; + + if ($s <= 10) { + return $s/(255*12.92); + } else { + return (($s+14.025)/269.025)**2.4; + } +} + +sub linear_to_srgb($) +{ + my($l) = @_; + my $s; + + if ($l <= 0.00304) { + $s = 12.92*$l; + } else { + $s = 1.055*$l**(1.0/2.4) - 0.055; + } + + return int($s*255+0.5); +} + +# Header +print "#include <inttypes.h>\n\n"; + +# +# Table 1: convert 8-bit sRGB values to 16-bit linear values +# + +print "const uint16_t __vesacon_srgb_to_linear[256] = {\n"; +for ($i = 0; $i <= 255; $i++) { + printf "\t%5d,\n", int(srgb_to_linear($i)*65535+0.5); +} +print "};\n\n"; + +# +# Table 2: convert linear values in the range [0, 65535*255], +# shifted right by 12 bits, to sRGB +# + +print "const uint8_t __vesacon_linear_to_srgb[4080] = {\n"; +for ($i = 0; $i <= 4079; $i++) { + printf "\t%3d,\n", linear_to_srgb(($i+0.5)/4079.937744); +} +print "};\n\n"; diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/background.c b/contrib/syslinux-4.02/com32/lib/sys/vesa/background.c new file mode 100644 index 0000000..9357746 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/background.c @@ -0,0 +1,456 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <stdio.h> +#include <png.h> +#include <tinyjpeg.h> +#include <com32.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <minmax.h> +#include <stdbool.h> +#include <ilog2.h> +#include <syslinux/loadfile.h> +#include "vesa.h" +#include "video.h" + +/*** FIX: This really should be alpha-blended with color index 0 ***/ + +/* For best performance, "start" should be a multiple of 4, to assure + aligned dwords. */ +static void draw_background_line(int line, int start, int npixels) +{ + uint32_t *bgptr = &__vesacon_background[line*__vesa_info.mi.h_res+start]; + unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; + size_t fbptr = line * __vesa_info.mi.logical_scan + start*bytes_per_pixel; + + __vesacon_copy_to_screen(fbptr, bgptr, npixels); +} + +/* This draws the border, then redraws the text area */ +static void draw_background(void) +{ + int i; + const int bottom_border = VIDEO_BORDER + + (TEXT_PIXEL_ROWS % __vesacon_font_height); + const int right_border = VIDEO_BORDER + (TEXT_PIXEL_COLS % FONT_WIDTH); + + for (i = 0; i < VIDEO_BORDER; i++) + draw_background_line(i, 0, __vesa_info.mi.h_res); + + for (i = VIDEO_BORDER; i < __vesa_info.mi.v_res - bottom_border; i++) { + draw_background_line(i, 0, VIDEO_BORDER); + draw_background_line(i, __vesa_info.mi.h_res - right_border, + right_border); + } + + for (i = __vesa_info.mi.v_res - bottom_border; + i < __vesa_info.mi.v_res; i++) + draw_background_line(i, 0, __vesa_info.mi.h_res); + + __vesacon_redraw_text(); +} + +/* + * Tile an image in the UL corner across the entire screen + */ +static void tile_image(int width, int height) +{ + int xsize = __vesa_info.mi.h_res; + int ysize = __vesa_info.mi.v_res; + int x, y, yr; + int xl, yl; + uint32_t *sp, *dp, *drp, *dtp; + + drp = __vesacon_background; + for (y = 0 ; y < ysize ; y += height) { + yl = min(height, ysize-y); + dtp = drp; + for (x = 0 ; x < xsize ; x += width) { + xl = min(width, xsize-x); + if (x || y) { + sp = __vesacon_background; + dp = dtp; + for (yr = 0 ; yr < yl ; yr++) { + memcpy(dp, sp, xl*sizeof(uint32_t)); + dp += xsize; + sp += xsize; + } + } + dtp += xl; + } + drp += xsize*height; + } +} + +static int read_png_file(FILE * fp) +{ + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; +#if 0 + png_color_16p image_background; + static const png_color_16 my_background = { 0, 0, 0, 0, 0 }; +#endif + png_bytep row_pointers[__vesa_info.mi.v_res], rp; + int i; + int rv = -1; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info_ptr = png_create_info_struct(png_ptr); + + if (!png_ptr || !info_ptr || setjmp(png_jmpbuf(png_ptr))) + goto err; + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, 8); + + png_set_user_limits(png_ptr, __vesa_info.mi.h_res, __vesa_info.mi.v_res); + + png_read_info(png_ptr, info_ptr); + + /* Set the appropriate set of transformations. We need to end up + with 32-bit BGRA format, no more, no less. */ + + /* Expand to RGB first... */ + if (info_ptr->color_type & PNG_COLOR_MASK_PALETTE) + png_set_palette_to_rgb(png_ptr); + else if (!(info_ptr->color_type & PNG_COLOR_MASK_COLOR)) + png_set_gray_to_rgb(png_ptr); + + /* Add alpha channel, if need be */ + if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA)) { + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + else + png_set_add_alpha(png_ptr, ~0, PNG_FILLER_AFTER); + } + + /* Adjust the byte order, if necessary */ + png_set_bgr(png_ptr); + + /* Make sure we end up with 8-bit data */ + if (info_ptr->bit_depth == 16) + png_set_strip_16(png_ptr); + else if (info_ptr->bit_depth < 8) + png_set_packing(png_ptr); + +#if 0 + if (png_get_bKGD(png_ptr, info_ptr, &image_background)) + png_set_background(png_ptr, image_background, + PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + else + png_set_background(png_ptr, &my_background, + PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); +#endif + + /* Whew! Now we should get the stuff we want... */ + rp = (png_bytep)__vesacon_background; + for (i = 0; i < (int)info_ptr->height; i++) { + row_pointers[i] = rp; + rp += __vesa_info.mi.h_res << 2; + } + + png_read_image(png_ptr, row_pointers); + + tile_image(info_ptr->width, info_ptr->height); + + rv = 0; + +err: + if (png_ptr) + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); + return rv; +} + +static int jpeg_sig_cmp(uint8_t * bytes, int len) +{ + (void)len; + + return (bytes[0] == 0xff && bytes[1] == 0xd8) ? 0 : -1; +} + +static int read_jpeg_file(FILE * fp, uint8_t * header, int len) +{ + struct jdec_private *jdec = NULL; + void *jpeg_file = NULL; + size_t length_of_file; + unsigned int width, height; + int rv = -1; + unsigned char *components[1]; + unsigned int bytes_per_row[1]; + + rv = floadfile(fp, &jpeg_file, &length_of_file, header, len); + fclose(fp); + if (rv) + goto err; + + jdec = tinyjpeg_init(); + if (!jdec) + goto err; + + if (tinyjpeg_parse_header(jdec, jpeg_file, length_of_file) < 0) + goto err; + + tinyjpeg_get_size(jdec, &width, &height); + if (width > __vesa_info.mi.h_res || height > __vesa_info.mi.v_res) + goto err; + + components[0] = (void *)__vesacon_background; + tinyjpeg_set_components(jdec, components, 1); + bytes_per_row[0] = __vesa_info.mi.h_res << 2; + tinyjpeg_set_bytes_per_row(jdec, bytes_per_row, 1); + + tinyjpeg_decode(jdec, TINYJPEG_FMT_BGRA32); + tile_image(width, height); + + rv = 0; + +err: + /* Don't use tinyjpeg_free() here, since we didn't allow tinyjpeg + to allocate the frame buffer */ + if (jdec) + free(jdec); + + if (jpeg_file) + free(jpeg_file); + + return rv; +} + +/* Simple grey Gaussian hole, enough to look interesting */ +int vesacon_default_background(void) +{ + int x, y, dx, dy, dy2; + int z; + unsigned int shft; + uint8_t *bgptr = (uint8_t *)__vesacon_background; + uint8_t k; + + if (__vesacon_pixel_format == PXF_NONE) + return 0; /* Not in graphics mode */ + + z = max(__vesa_info.mi.v_res, __vesa_info.mi.h_res) >> 1; + z = ((z*z) >> 11) - 1; + shft = ilog2(z) + 1; + + for (y = 0, dy = -(__vesa_info.mi.v_res >> 1); + y < __vesa_info.mi.v_res; y++, dy++) { + dy2 = dy * dy; + for (x = 0, dx = -(__vesa_info.mi.h_res >> 1); + x < __vesa_info.mi.h_res; x++, dx++) { + k = __vesacon_linear_to_srgb[500 + ((dx*dx + dy2) >> shft)]; + bgptr[0] = k; /* Blue */ + bgptr[1] = k; /* Green */ + bgptr[2] = k; /* Red */ + bgptr += 4; /* Dummy alpha */ + } + } + + draw_background(); + return 0; +} + +/* Set the background to a single flat color */ +int vesacon_set_background(unsigned int rgb) +{ + void *bgptr = __vesacon_background; + unsigned int count = __vesa_info.mi.h_res * __vesa_info.mi.v_res; + + if (__vesacon_pixel_format == PXF_NONE) + return 0; /* Not in graphics mode */ + + asm volatile ("rep; stosl":"+D" (bgptr), "+c"(count) + :"a"(rgb) + :"memory"); + + draw_background(); + return 0; +} + +struct lss16_header { + uint32_t magic; + uint16_t xsize; + uint16_t ysize; +}; + +#define LSS16_MAGIC 0x1413f33d + +static inline int lss16_sig_cmp(const void *header, int len) +{ + const struct lss16_header *h = header; + + if (len != 8) + return 1; + + return !(h->magic == LSS16_MAGIC && + h->xsize <= __vesa_info.mi.h_res && + h->ysize <= __vesa_info.mi.v_res); +} + +static int read_lss16_file(FILE * fp, const void *header, int header_len) +{ + const struct lss16_header *h = header; + uint32_t colors[16], color; + bool has_nybble; + uint8_t byte; + int count; + int nybble, prev; + enum state { + st_start, + st_c0, + st_c1, + st_c2, + } state; + int i, x, y; + uint32_t *bgptr = __vesacon_background; + + /* Assume the header, 8 bytes, has already been loaded. */ + if (header_len != 8) + return -1; + + for (i = 0; i < 16; i++) { + uint8_t rgb[3]; + if (fread(rgb, 1, 3, fp) != 3) + return -1; + + colors[i] = (((rgb[0] & 63) * 255 / 63) << 16) + + (((rgb[1] & 63) * 255 / 63) << 8) + + ((rgb[2] & 63) * 255 / 63); + } + + /* By spec, the state machine is per row */ + for (y = 0; y < h->ysize; y++) { + state = st_start; + has_nybble = false; + color = colors[prev = 0]; /* By specification */ + count = 0; + + x = 0; + while (x < h->xsize) { + if (!has_nybble) { + if (fread(&byte, 1, 1, fp) != 1) + return -1; + nybble = byte & 0xf; + has_nybble = true; + } else { + nybble = byte >> 4; + has_nybble = false; + } + + switch (state) { + case st_start: + if (nybble != prev) { + *bgptr++ = color = colors[prev = nybble]; + x++; + } else { + state = st_c0; + } + break; + + case st_c0: + if (nybble == 0) { + state = st_c1; + } else { + count = nybble; + goto do_run; + } + break; + + case st_c1: + count = nybble + 16; + state = st_c2; + break; + + case st_c2: + count += nybble << 4; + goto do_run; + +do_run: + count = min(count, h->xsize - x); + x += count; + asm volatile ("rep; stosl":"+D" (bgptr), + "+c"(count):"a"(color)); + state = st_start; + break; + } + } + + /* Zero-fill rest of row */ + i = __vesa_info.mi.h_res - x; + asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory"); + } + + /* Zero-fill rest of screen */ + i = (__vesa_info.mi.v_res - y) * __vesa_info.mi.h_res; + asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory"); + + return 0; +} + +int vesacon_load_background(const char *filename) +{ + FILE *fp = NULL; + uint8_t header[8]; + int rv = 1; + + if (__vesacon_pixel_format == PXF_NONE) + return 0; /* Not in graphics mode */ + + fp = fopen(filename, "r"); + + if (!fp) + goto err; + + if (fread(header, 1, 8, fp) != 8) + goto err; + + if (!png_sig_cmp(header, 0, 8)) { + rv = read_png_file(fp); + } else if (!jpeg_sig_cmp(header, 8)) { + rv = read_jpeg_file(fp, header, 8); + } else if (!lss16_sig_cmp(header, 8)) { + rv = read_lss16_file(fp, header, 8); + } + + /* This actually displays the stuff */ + draw_background(); + +err: + if (fp) + fclose(fp); + + return rv; +} + +int __vesacon_init_background(void) +{ + /* __vesacon_background was cleared by calloc() */ + + /* The VESA BIOS has already cleared the screen */ + return 0; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/debug.h b/contrib/syslinux-4.02/com32/lib/sys/vesa/debug.h new file mode 100644 index 0000000..86d085f --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/debug.h @@ -0,0 +1,36 @@ +#ifndef LIB_SYS_VESA_DEBUG_H +#define LIB_SYS_VESA_DEBUG_H + +#if 0 + +#include <stdio.h> +#include <unistd.h> + +ssize_t __serial_write(void *fp, const void *buf, size_t count); + +static void debug(const char *str, ...) +{ + va_list va; + char buf[65536]; + size_t len; + + va_start(va, str); + len = vsnprintf(buf, sizeof buf, str, va); + va_end(va); + + if (len >= sizeof buf) + len = sizeof buf - 1; + + __serial_write(NULL, buf, len); +} + +#else + +static inline void debug(const char *str, ...) +{ + (void)str; +} + +#endif + +#endif /* LIB_SYS_VESA_DEBUG_H */ diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/drawtxt.c b/contrib/syslinux-4.02/com32/lib/sys/vesa/drawtxt.c new file mode 100644 index 0000000..85a9e97 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/drawtxt.c @@ -0,0 +1,317 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <inttypes.h> +#include <colortbl.h> +#include <string.h> +#include "vesa.h" +#include "video.h" +#include "fill.h" + +/* + * Visible cursor information + */ +static uint8_t cursor_pattern[FONT_MAX_HEIGHT]; +static struct vesa_char *cursor_pointer = NULL; +static int cursor_x, cursor_y; + +static inline void *copy_dword(void *dst, void *src, size_t dword_count) +{ + asm volatile ("rep; movsl":"+D" (dst), "+S"(src), "+c"(dword_count)); + return dst; /* Updated destination pointer */ +} + +static inline __attribute__ ((always_inline)) +uint8_t alpha_val(uint8_t fg, uint8_t bg, uint8_t alpha) +{ + unsigned int tmp; + + tmp = __vesacon_srgb_to_linear[fg] * alpha; + tmp += __vesacon_srgb_to_linear[bg] * (255 - alpha); + + return __vesacon_linear_to_srgb[tmp >> 12]; +} + +static uint32_t alpha_pixel(uint32_t fg, uint32_t bg) +{ + uint8_t alpha = fg >> 24; + uint8_t fg_r = fg >> 16; + uint8_t fg_g = fg >> 8; + uint8_t fg_b = fg; + uint8_t bg_r = bg >> 16; + uint8_t bg_g = bg >> 8; + uint8_t bg_b = bg; + + return + (alpha_val(fg_r, bg_r, alpha) << 16) | + (alpha_val(fg_g, bg_g, alpha) << 8) | (alpha_val(fg_b, bg_b, alpha)); +} + +static void vesacon_update_characters(int row, int col, int nrows, int ncols) +{ + const int height = __vesacon_font_height; + const int width = FONT_WIDTH; + uint32_t *bgrowptr, *bgptr, bgval, fgval; + uint32_t fgcolor = 0, bgcolor = 0, color; + uint8_t chbits = 0, chxbits = 0, chsbits = 0; + int i, j, jx, pixrow, pixsrow; + struct vesa_char *rowptr, *rowsptr, *cptr, *csptr; + unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; + unsigned long pixel_offset; + uint32_t row_buffer[__vesa_info.mi.h_res], *rowbufptr; + size_t fbrowptr; + uint8_t sha; + + pixel_offset = ((row * height + VIDEO_BORDER) * __vesa_info.mi.h_res) + + (col * width + VIDEO_BORDER); + + bgrowptr = &__vesacon_background[pixel_offset]; + fbrowptr = (row * height + VIDEO_BORDER) * __vesa_info.mi.logical_scan + + (col * width + VIDEO_BORDER) * bytes_per_pixel; + + /* Note that we keep a 1-character guard area around the real text area... */ + rowptr = &__vesacon_text_display[(row+1)*(__vesacon_text_cols+2)+(col+1)]; + rowsptr = rowptr - ((__vesacon_text_cols+2)+1); + pixrow = 0; + pixsrow = height - 1; + + for (i = height * nrows; i >= 0; i--) { + bgptr = bgrowptr; + rowbufptr = row_buffer; + + cptr = rowptr; + csptr = rowsptr; + + chsbits = __vesacon_graphics_font[csptr->ch][pixsrow]; + if (__unlikely(csptr == cursor_pointer)) + chsbits |= cursor_pattern[pixsrow]; + sha = console_color_table[csptr->attr].shadow; + chsbits &= (sha & 0x02) ? 0xff : 0x00; + chsbits ^= (sha & 0x01) ? 0xff : 0x00; + chsbits <<= (width - 2); + csptr++; + + /* Draw two pixels beyond the end of the line. One for the shadow, + and one to make sure we have a whole dword of data for the copy + operation at the end. Note that this code depends on the fact that + all characters begin on dword boundaries in the frame buffer. */ + + for (jx = 1, j = width * ncols + 1; j >= 0; j--) { + chbits <<= 1; + chsbits <<= 1; + chxbits <<= 1; + + switch (jx) { + case 1: + chbits = __vesacon_graphics_font[cptr->ch][pixrow]; + if (__unlikely(cptr == cursor_pointer)) + chbits |= cursor_pattern[pixrow]; + sha = console_color_table[cptr->attr].shadow; + chxbits = chbits; + chxbits &= (sha & 0x02) ? 0xff : 0x00; + chxbits ^= (sha & 0x01) ? 0xff : 0x00; + fgcolor = console_color_table[cptr->attr].argb_fg; + bgcolor = console_color_table[cptr->attr].argb_bg; + cptr++; + jx--; + break; + case 0: + chsbits = __vesacon_graphics_font[csptr->ch][pixsrow]; + if (__unlikely(csptr == cursor_pointer)) + chsbits |= cursor_pattern[pixsrow]; + sha = console_color_table[csptr->attr].shadow; + chsbits &= (sha & 0x02) ? 0xff : 0x00; + chsbits ^= (sha & 0x01) ? 0xff : 0x00; + csptr++; + jx = width - 1; + break; + default: + jx--; + break; + } + + /* If this pixel is raised, use the offsetted value */ + bgval = (chxbits & 0x80) + ? bgptr[__vesa_info.mi.h_res + 1] : *bgptr; + bgptr++; + + /* If this pixel is set, use the fg color, else the bg color */ + fgval = (chbits & 0x80) ? fgcolor : bgcolor; + + /* Produce the combined color pixel value */ + color = alpha_pixel(fgval, bgval); + + /* Apply the shadow (75% shadow) */ + if ((chsbits & ~chxbits) & 0x80) { + color >>= 2; + color &= 0x3f3f3f; + } + + *rowbufptr++ = color; + } + + /* Copy to frame buffer */ + __vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr - row_buffer); + + bgrowptr += __vesa_info.mi.h_res; + fbrowptr += __vesa_info.mi.logical_scan; + + if (++pixrow == height) { + rowptr += __vesacon_text_cols + 2; + pixrow = 0; + } + if (++pixsrow == height) { + rowsptr += __vesacon_text_cols + 2; + pixsrow = 0; + } + } +} + +/* Bounding box for changed text. The (x1, y1) coordinates are +1! */ +static unsigned int upd_x0 = -1U, upd_x1, upd_y0 = -1U, upd_y1; + +/* Update the range already touched by various variables */ +void __vesacon_doit(void) +{ + if (upd_x1 > upd_x0 && upd_y1 > upd_y0) { + vesacon_update_characters(upd_y0, upd_x0, upd_y1 - upd_y0, + upd_x1 - upd_x0); + upd_x0 = upd_y0 = -1U; + upd_x1 = upd_y1 = 0; + } +} + +/* Mark a range for update; note argument sequence is the same as + vesacon_update_characters() */ +static inline void vesacon_touch(int row, int col, int rows, int cols) +{ + unsigned int y0 = row; + unsigned int x0 = col; + unsigned int y1 = y0 + rows; + unsigned int x1 = x0 + cols; + + if (y0 < upd_y0) + upd_y0 = y0; + if (y1 > upd_y1) + upd_y1 = y1; + if (x0 < upd_x0) + upd_x0 = x0; + if (x1 > upd_x1) + upd_x1 = x1; +} + +/* Erase a region of the screen */ +void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr) +{ + int y; + struct vesa_char *ptr = &__vesacon_text_display + [(y0 + 1) * (__vesacon_text_cols + 2) + (x0 + 1)]; + struct vesa_char fill = { + .ch = ' ', + .attr = attr, + }; + int ncols = x1 - x0 + 1; + + for (y = y0; y <= y1; y++) { + vesacon_fill(ptr, fill, ncols); + ptr += __vesacon_text_cols + 2; + } + + vesacon_touch(y0, x0, y1 - y0 + 1, ncols); +} + +/* Scroll the screen up */ +void __vesacon_scroll_up(int nrows, attr_t attr) +{ + struct vesa_char *fromptr = &__vesacon_text_display + [(nrows + 1) * (__vesacon_text_cols + 2)]; + struct vesa_char *toptr = &__vesacon_text_display + [(__vesacon_text_cols + 2)]; + int dword_count = + (__vesacon_text_rows - nrows) * (__vesacon_text_cols + 2); + struct vesa_char fill = { + .ch = ' ', + .attr = attr, + }; + + toptr = copy_dword(toptr, fromptr, dword_count); + + dword_count = nrows * (__vesacon_text_cols + 2); + + vesacon_fill(toptr, fill, dword_count); + + vesacon_touch(0, 0, __vesacon_text_rows, __vesacon_text_cols); +} + +/* Draw one character text at a specific area of the screen */ +void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr) +{ + struct vesa_char *ptr = &__vesacon_text_display + [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)]; + + ptr->ch = ch; + ptr->attr = attr; + + vesacon_touch(y, x, 1, 1); +} + +void __vesacon_set_cursor(int x, int y, bool visible) +{ + struct vesa_char *ptr = &__vesacon_text_display + [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)]; + + if (cursor_pointer) + vesacon_touch(cursor_y, cursor_x, 1, 1); + + if (!visible) { + /* Invisible cursor */ + cursor_pointer = NULL; + } else { + cursor_pointer = ptr; + vesacon_touch(y, x, 1, 1); + } + + cursor_x = x; + cursor_y = y; +} + +void __vesacon_init_cursor(int font_height) +{ + int r0 = font_height - (font_height < 10 ? 2 : 3); + + if (r0 < 0) + r0 = 0; + + memset(cursor_pattern, 0, font_height); + cursor_pattern[r0] = 0xff; + cursor_pattern[r0 + 1] = 0xff; +} + +void __vesacon_redraw_text(void) +{ + vesacon_update_characters(0, 0, __vesacon_text_rows, __vesacon_text_cols); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/fill.h b/contrib/syslinux-4.02/com32/lib/sys/vesa/fill.h new file mode 100644 index 0000000..5a43c72 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/fill.h @@ -0,0 +1,63 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#ifndef LIB_SYS_VESA_FILL_H +#define LIB_SYS_VESA_FILL_H + +#include "video.h" + +/* Fill a number of characters. */ +static inline struct vesa_char *vesacon_fill(struct vesa_char *ptr, + struct vesa_char fill, + unsigned int count) +{ + switch (sizeof(struct vesa_char)) { + case 1: + asm volatile ("rep; stosb":"+D" (ptr), "+c"(count) + :"a"(fill) + :"memory"); + break; + case 2: + asm volatile ("rep; stosw":"+D" (ptr), "+c"(count) + :"a"(fill) + :"memory"); + break; + case 4: + asm volatile ("rep; stosl":"+D" (ptr), "+c"(count) + :"a"(fill) + :"memory"); + break; + default: + while (count--) + *ptr++ = fill; + break; + } + + return ptr; +} + +#endif /* LIB_SYS_VESA_FILL_H */ diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/fmtpixel.c b/contrib/syslinux-4.02/com32/lib/sys/vesa/fmtpixel.c new file mode 100644 index 0000000..381fc21 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/fmtpixel.c @@ -0,0 +1,101 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * fmtpixel.c + * + * Functions to format a single pixel + */ + +#include <inttypes.h> +#include "video.h" + +/* + * Format a sequence of pixels. The first argument is the line buffer; + * we can use it to write up to 4 bytes past the end of the last pixel. + * Return the place we should be copying from, this is usually the + * buffer address, but doesn't *have* to be. + */ + +static const void *format_pxf_bgra32(void *ptr, const uint32_t * p, size_t n) +{ + (void)ptr; + (void)n; + return p; /* No conversion needed! */ +} + +static const void *format_pxf_bgr24(void *ptr, const uint32_t * p, size_t n) +{ + char *q = ptr; + + while (n--) { + *(uint32_t *) q = *p++; + q += 3; + } + return ptr; +} + +static const void *format_pxf_le_rgb16_565(void *ptr, const uint32_t * p, + size_t n) +{ + uint32_t bgra; + uint16_t *q = ptr; + + while (n--) { + bgra = *p++; + *q++ = + ((bgra >> 3) & 0x1f) + + ((bgra >> (2 + 8 - 5)) & (0x3f << 5)) + + ((bgra >> (3 + 16 - 11)) & (0x1f << 11)); + } + return ptr; +} + +static const void *format_pxf_le_rgb15_555(void *ptr, const uint32_t * p, + size_t n) +{ + uint32_t bgra; + uint16_t *q = ptr; + + while (n--) { + bgra = *p++; + *q++ = + ((bgra >> 3) & 0x1f) + + ((bgra >> (2 + 8 - 5)) & (0x1f << 5)) + + ((bgra >> (3 + 16 - 10)) & (0x1f << 10)); + } + return ptr; +} + +__vesacon_format_pixels_t __vesacon_format_pixels; + +const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE] = { + [PXF_BGRA32] = format_pxf_bgra32, + [PXF_BGR24] = format_pxf_bgr24, + [PXF_LE_RGB16_565] = format_pxf_le_rgb16_565, + [PXF_LE_RGB15_555] = format_pxf_le_rgb15_555, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/i915resolution.c b/contrib/syslinux-4.02/com32/lib/sys/vesa/i915resolution.c new file mode 100644 index 0000000..6ebb04d --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/i915resolution.c @@ -0,0 +1,795 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2010 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * Based on: + * + * 915 resolution by steve tomljenovic + * + * This was tested only on Sony VGN-FS550. Use at your own risk + * + * This code is based on the techniques used in : + * + * - 855patch. Many thanks to Christian Zietz (czietz gmx net) + * for demonstrating how to shadow the VBIOS into system RAM + * and then modify it. + * + * - 1280patch by Andrew Tipton (andrewtipton null li). + * + * - 855resolution by Alain Poirier + * + * This source code is into the public domain. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#define __USE_GNU +#include <string.h> +#include <sys/io.h> +#include <sys/cpu.h> +#include <sys/pci.h> +#include <unistd.h> +#include <assert.h> +#include <stdbool.h> +#include "video.h" +#include "debug.h" + +#define VBIOS_START 0xc0000 +#define VBIOS_SIZE 0x10000 + +#define MODE_TABLE_OFFSET_845G 617 + +#define VERSION "0.5.3" + +#define ATI_SIGNATURE1 "ATI MOBILITY RADEON" +#define ATI_SIGNATURE2 "ATI Technologies Inc" +#define NVIDIA_SIGNATURE "NVIDIA Corp" +#define INTEL_SIGNATURE "Intel Corp" + +typedef unsigned char * address; + +typedef enum { + CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM, + CT_945G, CT_945GM, CT_946GZ, CT_G965, CT_Q965, CT_945GME, + CHIPSET_TYPES +} chipset_type; + +typedef enum { + BT_UNKWN, BT_1, BT_2, BT_3 +} bios_type; + +static int freqs[] = { 60, 75, 85 }; + +typedef struct { + uint8_t mode; + uint8_t bits_per_pixel; + uint16_t resolution; + uint8_t unknown; +} __attribute__((packed)) vbios_mode; + +typedef struct { + uint16_t clock; /* Clock frequency in 10 kHz */ + uint8_t x1; + uint8_t x_total; + uint8_t x2; + uint8_t y1; + uint8_t y_total; + uint8_t y2; +} __attribute__((packed)) vbios_resolution_type1; + +typedef struct { + uint32_t clock; + + uint16_t x1; + uint16_t htotal; + uint16_t x2; + uint16_t hblank; + uint16_t hsyncstart; + uint16_t hsyncend; + + uint16_t y1; + uint16_t vtotal; + uint16_t y2; + uint16_t vblank; + uint16_t vsyncstart; + uint16_t vsyncend; +} __attribute__((packed)) vbios_modeline_type2; + +typedef struct { + uint8_t xchars; + uint8_t ychars; + uint8_t unknown[4]; + + vbios_modeline_type2 modelines[]; +} __attribute__((packed)) vbios_resolution_type2; + +typedef struct { + uint32_t clock; + + uint16_t x1; + uint16_t htotal; + uint16_t x2; + uint16_t hblank; + uint16_t hsyncstart; + uint16_t hsyncend; + + uint16_t y1; + uint16_t vtotal; + uint16_t y2; + uint16_t vblank; + uint16_t vsyncstart; + uint16_t vsyncend; + + uint16_t timing_h; + uint16_t timing_v; + + uint8_t unknown[6]; +} __attribute__((packed)) vbios_modeline_type3; + +typedef struct { + unsigned char unknown[6]; + + vbios_modeline_type3 modelines[]; +} __attribute__((packed)) vbios_resolution_type3; + + +typedef struct { + unsigned int chipset_id; + chipset_type chipset; + bios_type bios; + + address bios_ptr; + + vbios_mode * mode_table; + unsigned int mode_table_size; + + uint8_t b1, b2; + + bool unlocked; +} vbios_map; + +#if 0 /* Debugging hacks */ +static void good_marker(int x) +{ + ((uint16_t *)0xb8000)[x] = 0x2f30 - ((x & 0xf0) << 4) + (x & 0x0f); +} + +static void bad_marker(int x) +{ + ((uint16_t *)0xb8000)[x] = 0x4f30 - ((x & 0xf0) << 4) + (x & 0x0f); +} + +static void status(const char *fmt, ...) +{ + va_list ap; + char msg[81], *p; + int i; + uint16_t *q; + + memset(msg, 0, sizeof msg); + va_start(ap, fmt); + vsnprintf(msg, sizeof msg, fmt, ap); + va_end(ap); + p = msg; + q = (uint16_t *)0xb8000 + 80; + for (i = 0; i < 80; i++) + *q++ = *p++ + 0x1f00; +} +#else +static inline void good_marker(int x) { (void)x; } +static inline void bad_marker(int x) { (void)x; } +static inline void status(const char *fmt, ...) { (void)fmt; } +#endif + +static unsigned int get_chipset_id(void) { + return pci_readl(0x80000000); +} + +static chipset_type get_chipset(unsigned int id) { + chipset_type type; + + switch (id) { + case 0x35758086: + type = CT_830; + break; + + case 0x25608086: + type = CT_845G; + break; + + case 0x35808086: + type = CT_855GM; + break; + + case 0x25708086: + type = CT_865G; + break; + + case 0x25808086: + type = CT_915G; + break; + + case 0x25908086: + type = CT_915GM; + break; + + case 0x27708086: + type = CT_945G; + break; + + case 0x27a08086: + type = CT_945GM; + break; + + case 0x29708086: + type = CT_946GZ; + break; + + case 0x29a08086: + type = CT_G965; + break; + + case 0x29908086: + type = CT_Q965; + break; + + case 0x27ac8086: + type = CT_945GME; + break; + + default: + type = CT_UNKWN; + break; + } + + return type; +} + + +static vbios_resolution_type1 * map_type1_resolution(vbios_map * map, + uint16_t res) +{ + vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res)); + return ptr; +} + +static vbios_resolution_type2 * map_type2_resolution(vbios_map * map, + uint16_t res) +{ + vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res)); + return ptr; +} + +static vbios_resolution_type3 * map_type3_resolution(vbios_map * map, + uint16_t res) +{ + vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res)); + return ptr; +} + + +static bool detect_bios_type(vbios_map * map, int entry_size) +{ + unsigned int i; + uint16_t r1, r2; + + r1 = r2 = 32000; + + for (i = 0; i < map->mode_table_size; i++) { + if (map->mode_table[i].resolution <= r1) { + r1 = map->mode_table[i].resolution; + } else if (map->mode_table[i].resolution <= r2) { + r2 = map->mode_table[i].resolution; + } + } + + return ((r2-r1-6) % entry_size) == 0; +} + +static inline void close_vbios(vbios_map *map) +{ + (void)map; +} + +static vbios_map * open_vbios(void) +{ + static vbios_map _map; + vbios_map * const map = &_map; + + memset(&_map, 0, sizeof _map); + + /* + * Determine chipset + */ + map->chipset_id = get_chipset_id(); + good_marker(0x10); + map->chipset = get_chipset(map->chipset_id); + good_marker(0x11); + + /* + * Map the video bios to memory + */ + map->bios_ptr = (void *)VBIOS_START; + + /* + * check if we have ATI Radeon + */ + + if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) || + memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) { + debug("ATI chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n"); + return NULL; + } + + /* + * check if we have NVIDIA + */ + + if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) { + debug("NVIDIA chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n"); + return NULL; + } + + /* + * check if we have Intel + */ + + if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) { + debug("Intel chipset detected. However, 915resolution was unable to determine the chipset type.\r\n"); + + debug("Chipset Id: %x\r\n", map->chipset_id); + + debug("Please report this problem to stomljen@yahoo.com\r\n"); + + close_vbios(map); + return NULL; + } + + /* + * check for others + */ + + if (map->chipset == CT_UNKWN) { + debug("Unknown chipset type and unrecognized bios.\r\n"); + debug("915resolution only works with Intel 800/900 series graphic chipsets.\r\n"); + + debug("Chipset Id: %x\r\n", map->chipset_id); + close_vbios(map); + return NULL; + } + + /* + * Figure out where the mode table is + */ + good_marker(0x12); + + { + address p = map->bios_ptr + 16; + address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode)); + + while (p < limit && map->mode_table == 0) { + vbios_mode * mode_ptr = (vbios_mode *) p; + + if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) && + ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) { + + map->mode_table = mode_ptr; + } + + p++; + } + + if (map->mode_table == 0) { + debug("Unable to locate the mode table.\r\n"); + close_vbios(map); + return NULL; + } + } + good_marker(0x13); + + /* + * Determine size of mode table + */ + + { + vbios_mode * mode_ptr = map->mode_table; + + while (mode_ptr->mode != 0xff) { + map->mode_table_size++; + mode_ptr++; + } + } + good_marker(0x14); + status("mode_table_size = %d", map->mode_table_size); + + /* + * Figure out what type of bios we have + * order of detection is important + */ + + if (detect_bios_type(map, sizeof(vbios_modeline_type3))) { + map->bios = BT_3; + } + else if (detect_bios_type(map, sizeof(vbios_modeline_type2))) { + map->bios = BT_2; + } + else if (detect_bios_type(map, sizeof(vbios_resolution_type1))) { + map->bios = BT_1; + } + else { + debug("Unable to determine bios type.\r\n"); + debug("Mode Table Offset: $C0000 + $%x\r\n", ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr)); + debug("Mode Table Entries: %u\r\n", map->mode_table_size); + bad_marker(0x15); + return NULL; + } + good_marker(0x15); + + return map; +} + +static void unlock_vbios(vbios_map * map) +{ + assert(!map->unlocked); + + map->unlocked = true; + + switch (map->chipset) { + case CT_UNKWN: + case CHIPSET_TYPES: /* Shut up gcc */ + break; + case CT_830: + case CT_855GM: + map->b1 = pci_readb(0x8000005a); + pci_writeb(0x33, 0x8000005a); + break; + case CT_845G: + case CT_865G: + case CT_915G: + case CT_915GM: + case CT_945G: + case CT_945GM: + case CT_945GME: + case CT_946GZ: + case CT_G965: + case CT_Q965: + map->b1 = pci_readb(0x80000091); + map->b2 = pci_readb(0x80000092); + pci_writeb(0x33, 0x80000091); + pci_writeb(0x33, 0x80000092); + break; + } + +#if DEBUG + { + unsigned int t = inl(0xcfc); + debug("unlock PAM: (0x%08x)\r\n", t); + } +#endif +} + +static void relock_vbios(vbios_map * map) +{ + assert(map->unlocked); + map->unlocked = false; + + switch (map->chipset) { + case CT_UNKWN: + case CHIPSET_TYPES: /* Shut up gcc */ + break; + case CT_830: + case CT_855GM: + pci_writeb(map->b1, 0x8000005a); + break; + case CT_845G: + case CT_865G: + case CT_915G: + case CT_915GM: + case CT_945G: + case CT_945GM: + case CT_945GME: + case CT_946GZ: + case CT_G965: + case CT_Q965: + pci_writeb(map->b1, 0x80000091); + pci_writeb(map->b2, 0x80000092); + break; + } + +#if DEBUG + { + unsigned int t = inl(0xcfc); + debug("relock PAM: (0x%08x)\r\n", t); + } +#endif +} + +#if 0 +static void list_modes(vbios_map *map, unsigned int raw) +{ + unsigned int i, x, y; + + for (i=0; i < map->mode_table_size; i++) { + switch(map->bios) { + case BT_1: + { + vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution); + + x = ((((unsigned int) res->x2) & 0xf0) << 4) | res->x1; + y = ((((unsigned int) res->y2) & 0xf0) << 4) | res->y1; + + if (x != 0 && y != 0) { + debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); + } + + if (raw) + { + debug("Mode %02x (raw) :\r\n\t%02x %02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2); + } + + } + break; + case BT_2: + { + vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution); + + x = res->modelines[0].x1+1; + y = res->modelines[0].y1+1; + + if (x != 0 && y != 0) { + debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); + } + } + break; + case BT_3: + { + vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution); + + x = res->modelines[0].x1+1; + y = res->modelines[0].y1+1; + + if (x != 0 && y != 0) { + debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); + } + } + break; + case BT_UNKWN: + break; + } + } +} +#endif + +static void gtf_timings(int x, int y, int freq, uint32_t *clock, + uint16_t *hsyncstart, uint16_t *hsyncend, uint16_t *hblank, + uint16_t *vsyncstart, uint16_t *vsyncend, uint16_t *vblank) +{ + int hbl, vbl, vfreq; + + vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5; + vfreq = vbl * freq; + hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) / + (70.0 + 300000.0 / vfreq) / 16.0 + 0.5); + + *vsyncstart = y; + *vsyncend = y + 3; + *vblank = vbl - 1; + *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1; + *hsyncend = x + hbl / 2 - 1; + *hblank = x + hbl - 1; + *clock = (x + hbl) * vfreq / 1000; +} + +static int set_mode(vbios_map * map, unsigned int mode, + unsigned int x, unsigned int y, unsigned int bp, + unsigned int htotal, unsigned int vtotal) +{ + int xprev, yprev; + unsigned int i, j; + int rv = -1; + + for (i=0; i < map->mode_table_size; i++) { + if (map->mode_table[i].mode == mode) { + switch(map->bios) { + case BT_1: + { + vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution); + uint32_t clock; + uint16_t hsyncstart, hsyncend, hblank; + uint16_t vsyncstart, vsyncend, vblank; + + if (bp) { + map->mode_table[i].bits_per_pixel = bp; + } + + gtf_timings(x, y, freqs[0], &clock, + &hsyncstart, &hsyncend, &hblank, + &vsyncstart, &vsyncend, &vblank); + + status("x = %d, y = %d, clock = %lu, h = %d %d %d, v = %d %d %d\n", + x, y, clock, + hsyncstart, hsyncend, hblank, + vsyncstart, vsyncend, vblank); + + htotal = htotal ? htotal : (unsigned int)hblank+1; + vtotal = vtotal ? vtotal : (unsigned int)vblank+1; + + res->clock = clock/10; /* Units appear to be 10 kHz */ + res->x2 = (((htotal-x) >> 8) & 0x0f) | ((x >> 4) & 0xf0); + res->x1 = (x & 0xff); + + res->y2 = (((vtotal-y) >> 8) & 0x0f) | ((y >> 4) & 0xf0); + res->y1 = (y & 0xff); + if (htotal) + res->x_total = ((htotal-x) & 0xff); + + if (vtotal) + res->y_total = ((vtotal-y) & 0xff); + + rv = 0; + } + break; + case BT_2: + { + vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution); + + res->xchars = x / 8; + res->ychars = y / 16 - 1; + xprev = res->modelines[0].x1; + yprev = res->modelines[0].y1; + + for(j=0; j < 3; j++) { + vbios_modeline_type2 * modeline = &res->modelines[j]; + + if (modeline->x1 == xprev && modeline->y1 == yprev) { + modeline->x1 = modeline->x2 = x-1; + modeline->y1 = modeline->y2 = y-1; + + gtf_timings(x, y, freqs[j], &modeline->clock, + &modeline->hsyncstart, &modeline->hsyncend, + &modeline->hblank, &modeline->vsyncstart, + &modeline->vsyncend, &modeline->vblank); + + if (htotal) + modeline->htotal = htotal; + else + modeline->htotal = modeline->hblank; + + if (vtotal) + modeline->vtotal = vtotal; + else + modeline->vtotal = modeline->vblank; + } + } + + rv = 0; + } + break; + case BT_3: + { + vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution); + + xprev = res->modelines[0].x1; + yprev = res->modelines[0].y1; + + for (j=0; j < 3; j++) { + vbios_modeline_type3 * modeline = &res->modelines[j]; + + if (modeline->x1 == xprev && modeline->y1 == yprev) { + modeline->x1 = modeline->x2 = x-1; + modeline->y1 = modeline->y2 = y-1; + + gtf_timings(x, y, freqs[j], &modeline->clock, + &modeline->hsyncstart, &modeline->hsyncend, + &modeline->hblank, &modeline->vsyncstart, + &modeline->vsyncend, &modeline->vblank); + if (htotal) + modeline->htotal = htotal; + else + modeline->htotal = modeline->hblank; + if (vtotal) + modeline->vtotal = vtotal; + else + modeline->vtotal = modeline->vblank; + + modeline->timing_h = y-1; + modeline->timing_v = x-1; + } + } + + rv = 0; + } + break; + case BT_UNKWN: + break; + } + } + } + + return rv; +} + +static inline void display_map_info(vbios_map * map) { +#ifdef DEBUG + static const char * bios_type_names[] = + {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"}; + static const char * chipset_type_names[] = { + "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", + "945GM", "946GZ", "G965", "Q965", "945GME" + }; + + debug("Chipset: %s\r\n", chipset_type_names[map->chipset]); + debug("BIOS: %s\r\n", bios_type_names[map->bios]); + + debug("Mode Table Offset: $C0000 + $%x\r\n", + ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr)); + debug("Mode Table Entries: %u\r\n", map->mode_table_size); +#endif + (void)map; +} + +int __vesacon_i915resolution(int x, int y) +{ + vbios_map * map; + unsigned int mode = 0x52; /* 800x600x32 mode in known BIOSes */ + unsigned int bp = 32; /* 32 bits per pixel */ + int rv = 0; + + good_marker(0); + + map = open_vbios(); + if (!map) + return -1; + + good_marker(1); + + display_map_info(map); + + debug("\r\n"); + + if (mode && x && y) { + good_marker(2); + cli(); + good_marker(3); + unlock_vbios(map); + good_marker(4); + rv = set_mode(map, mode, x, y, bp, 0, 0); + if (rv) + bad_marker(5); + else + good_marker(5); + relock_vbios(map); + good_marker(6); + sti(); + + debug("Patch mode %02x to resolution %dx%d complete\r\n", mode, x, y); + } + close_vbios(map); + + return rv; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/initvesa.c b/contrib/syslinux-4.02/com32/lib/sys/vesa/initvesa.c new file mode 100644 index 0000000..9a1ae38 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/initvesa.c @@ -0,0 +1,357 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * initvesa.c + * + * Query the VESA BIOS and select a 640x480x32 mode with local mapping + * support, if one exists. + */ + +#include <inttypes.h> +#include <com32.h> +#include <stdlib.h> +#include <string.h> +#include <sys/fpu.h> +#include <syslinux/video.h> +#include "vesa.h" +#include "video.h" +#include "fill.h" +#include "debug.h" + +struct vesa_info __vesa_info; + +struct vesa_char *__vesacon_text_display; + +int __vesacon_font_height; +int __vesacon_text_rows; +int __vesacon_text_cols; +enum vesa_pixel_format __vesacon_pixel_format = PXF_NONE; +unsigned int __vesacon_bytes_per_pixel; +uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT]; + +uint32_t *__vesacon_background, *__vesacon_shadowfb; + +static void unpack_font(uint8_t * dst, uint8_t * src, int height) +{ + int i; + + for (i = 0; i < FONT_MAX_CHARS; i++) { + memcpy(dst, src, height); + memset(dst + height, 0, FONT_MAX_HEIGHT - height); + + dst += FONT_MAX_HEIGHT; + src += height; + } +} + +static int __constfunc is_power_of_2(unsigned int x) +{ + return x && !(x & (x - 1)); +} + +static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi) +{ + int i; + + if (!is_power_of_2(mi->win_size) || + !is_power_of_2(mi->win_grain) || mi->win_grain > mi->win_size) + return 0; /* Impossible... */ + + for (i = 0; i < 2; i++) { + if ((mi->win_attr[i] & 0x05) == 0x05 && mi->win_seg[i]) + return 1; /* Usable window */ + } + + return 0; /* Nope... */ +} + +static int vesacon_set_mode(int x, int y) +{ + com32sys_t rm; + uint8_t *rom_font; + uint16_t mode, bestmode, *mode_ptr; + struct vesa_info *vi; + struct vesa_general_info *gi; + struct vesa_mode_info *mi; + enum vesa_pixel_format pxf, bestpxf; + int err = 0; + + debug("Hello, World!\r\n"); + + /* Free any existing data structures */ + if (__vesacon_background) { + free(__vesacon_background); + __vesacon_background = NULL; + } + if (__vesacon_shadowfb) { + free(__vesacon_shadowfb); + __vesacon_shadowfb = NULL; + } + + /* Allocate space in the bounce buffer for these structures */ + vi = lzalloc(sizeof *vi); + if (!vi) { + err = 10; /* Out of memory */ + goto exit; + } + gi = &vi->gi; + mi = &vi->mi; + + memset(&rm, 0, sizeof rm); + + gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */ + rm.eax.w[0] = 0x4F00; /* Get SVGA general information */ + rm.edi.w[0] = OFFS(gi); + rm.es = SEG(gi); + __intcall(0x10, &rm, &rm); + + if (rm.eax.w[0] != 0x004F) { + err = 1; /* Function call failed */ + goto exit; + } + if (gi->signature != VESA_MAGIC) { + err = 2; /* No magic */ + goto exit; + } + if (gi->version < 0x0102) { + err = 3; /* VESA 1.2+ required */ + goto exit; + } + + /* Copy general info */ + memcpy(&__vesa_info.gi, gi, sizeof *gi); + + /* Search for the proper mode with a suitable color and memory model... */ + + mode_ptr = GET_PTR(gi->video_mode_ptr); + bestmode = 0; + bestpxf = PXF_NONE; + + while ((mode = *mode_ptr++) != 0xFFFF) { + mode &= 0x1FF; /* The rest are attributes of sorts */ + + debug("Found mode: 0x%04x\r\n", mode); + + memset(mi, 0, sizeof *mi); + rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */ + rm.ecx.w[0] = mode; + rm.edi.w[0] = OFFS(mi); + rm.es = SEG(mi); + __intcall(0x10, &rm, &rm); + + /* Must be a supported mode */ + if (rm.eax.w[0] != 0x004f) + continue; + + debug + ("mode_attr 0x%04x, h_res = %4d, v_res = %4d, bpp = %2d, layout = %d (%d,%d,%d)\r\n", + mi->mode_attr, mi->h_res, mi->v_res, mi->bpp, mi->memory_layout, + mi->rpos, mi->gpos, mi->bpos); + + /* Must be an LFB color graphics mode supported by the hardware. + + The bits tested are: + 4 - graphics mode + 3 - color mode + 1 - mode information available (mandatory in VBE 1.2+) + 0 - mode supported by hardware + */ + if ((mi->mode_attr & 0x001b) != 0x001b) + continue; + + /* Must be the chosen size */ + if (mi->h_res != x || mi->v_res != y) + continue; + + /* We don't support multibank (interlaced memory) modes */ + /* + * Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the + * specification which states that banks == 1 for unbanked modes; + * fortunately it does report bank_size == 0 for those. + */ + if (mi->banks > 1 && mi->bank_size) { + debug("bad: banks = %d, banksize = %d, pages = %d\r\n", + mi->banks, mi->bank_size, mi->image_pages); + continue; + } + + /* Must be either a flat-framebuffer mode, or be an acceptable + paged mode */ + if (!(mi->mode_attr & 0x0080) && !vesacon_paged_mode_ok(mi)) { + debug("bad: invalid paged mode\r\n"); + continue; + } + + /* Must either be a packed-pixel mode or a direct color mode + (depending on VESA version ); must be a supported pixel format */ + pxf = PXF_NONE; /* Not usable */ + + if (mi->bpp == 32 && + (mi->memory_layout == 4 || + (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && + mi->bpos == 0))) + pxf = PXF_BGRA32; + else if (mi->bpp == 24 && + (mi->memory_layout == 4 || + (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && + mi->bpos == 0))) + pxf = PXF_BGR24; + else if (mi->bpp == 16 && + (mi->memory_layout == 4 || + (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 && + mi->bpos == 0))) + pxf = PXF_LE_RGB16_565; + else if (mi->bpp == 15 && + (mi->memory_layout == 4 || + (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 && + mi->bpos == 0))) + pxf = PXF_LE_RGB15_555; + + if (pxf < bestpxf) { + debug("Best mode so far, pxf = %d\r\n", pxf); + + /* Best mode so far... */ + bestmode = mode; + bestpxf = pxf; + + /* Copy mode info */ + memcpy(&__vesa_info.mi, mi, sizeof *mi); + } + } + + if (bestpxf == PXF_NONE) { + err = 4; /* No mode found */ + goto exit; + } + + mi = &__vesa_info.mi; + mode = bestmode; + __vesacon_bytes_per_pixel = (mi->bpp + 7) >> 3; + __vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf]; + + /* Download the SYSLINUX- or BIOS-provided font */ + __vesacon_font_height = syslinux_font_query(&rom_font); + if (!__vesacon_font_height) { + /* Get BIOS 8x16 font */ + + rm.eax.w[0] = 0x1130; /* Get Font Information */ + rm.ebx.w[0] = 0x0600; /* Get 8x16 ROM font */ + __intcall(0x10, &rm, &rm); + rom_font = MK_PTR(rm.es, rm.ebp.w[0]); + __vesacon_font_height = 16; + } + unpack_font((uint8_t *) __vesacon_graphics_font, rom_font, + __vesacon_font_height); + + /* Now set video mode */ + rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */ + if (mi->mode_attr & 0x0080) + mode |= 0x4000; /* Request linear framebuffer if supported */ + rm.ebx.w[0] = mode; + __intcall(0x10, &rm, &rm); + if (rm.eax.w[0] != 0x004F) { + err = 9; /* Failed to set mode */ + goto exit; + } + + __vesacon_background = calloc(mi->h_res*mi->v_res, 4); + __vesacon_shadowfb = calloc(mi->h_res*mi->v_res, 4); + + __vesacon_init_copy_to_screen(); + + /* Tell syslinux we changed video mode */ + /* In theory this should be: + + flags = (mi->mode_attr & 4) ? 0x0007 : 0x000f; + + However, that would assume all systems that claim to handle text + output in VESA modes actually do that... */ + syslinux_report_video_mode(0x000f, mi->h_res, mi->v_res); + + __vesacon_pixel_format = bestpxf; + +exit: + if (vi) + lfree(vi); + + return err; +} + +static int init_text_display(void) +{ + size_t nchars; + struct vesa_char *ptr; + struct vesa_char def_char = { + .ch = ' ', + .attr = 0, + }; + + if (__vesacon_text_display) + free(__vesacon_text_display); + + __vesacon_text_cols = TEXT_PIXEL_COLS / FONT_WIDTH; + __vesacon_text_rows = TEXT_PIXEL_ROWS / __vesacon_font_height; + nchars = (__vesacon_text_cols+2) * (__vesacon_text_rows+2); + + __vesacon_text_display = ptr = malloc(nchars * sizeof(struct vesa_char)); + + if (!ptr) + return -1; + + vesacon_fill(ptr, def_char, nchars); + __vesacon_init_cursor(__vesacon_font_height); + + return 0; +} + +int __vesacon_init(int x, int y) +{ + int rv; + + /* We need the FPU for graphics, at least libpng et al will need it... */ + if (x86_init_fpu()) + return 10; + + rv = vesacon_set_mode(x, y); + if (rv) { + /* Try to see if we can just patch the BIOS... */ + if (__vesacon_i915resolution(x, y)) + return rv; + if (vesacon_set_mode(x, y)) + return rv; + } + + init_text_display(); + + debug("Mode set, now drawing at %#p\r\n", __vesa_info.mi.lfb_ptr); + + __vesacon_init_background(); + + debug("Ready!\r\n"); + return 0; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/screencpy.c b/contrib/syslinux-4.02/com32/lib/sys/vesa/screencpy.c new file mode 100644 index 0000000..32dce9e --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/screencpy.c @@ -0,0 +1,117 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <inttypes.h> +#include <minmax.h> +#include <klibc/compiler.h> +#include <string.h> +#include <com32.h> +#include <ilog2.h> +#include "vesa.h" +#include "video.h" + +static struct win_info { + char *win_base; + size_t win_pos; + size_t win_size; + int win_gshift; + int win_num; +} wi; + +void __vesacon_init_copy_to_screen(void) +{ + struct vesa_mode_info *const mi = &__vesa_info.mi; + int winn; + + if (mi->mode_attr & 0x0080) { + /* Linear frame buffer */ + + wi.win_base = (char *)mi->lfb_ptr; + wi.win_size = 1 << 31; /* 2 GB, i.e. one huge window */ + wi.win_pos = 0; /* Already positioned (only one position...) */ + wi.win_num = -1; /* Not a window */ + } else { + /* Paged frame buffer */ + + /* We have already tested that *one* of these is usable */ + if ((mi->win_attr[0] & 0x05) == 0x05 && mi->win_seg[0]) + winn = 0; + else + winn = 1; + + wi.win_num = winn; + wi.win_base = (char *)(mi->win_seg[winn] << 4); + wi.win_size = mi->win_size << 10; + wi.win_gshift = ilog2(mi->win_grain) + 10; + wi.win_pos = -1; /* Undefined position */ + } +} + +static void set_window_pos(size_t win_pos) +{ + static com32sys_t ireg; + + wi.win_pos = win_pos; + + if (wi.win_num < 0) + return; /* This should never happen... */ + + ireg.eax.w[0] = 0x4F05; + ireg.ebx.b[0] = wi.win_num; + ireg.edx.w[0] = win_pos >> wi.win_gshift; + + __intcall(0x10, &ireg, NULL); +} + +void __vesacon_copy_to_screen(size_t dst, const uint32_t * src, size_t npixels) +{ + size_t win_pos, win_off; + size_t win_size = wi.win_size; + size_t omask = win_size - 1; + char *win_base = wi.win_base; + size_t l; + size_t bytes = npixels * __vesacon_bytes_per_pixel; + char rowbuf[bytes + 4] __aligned(4); + const char *s; + + s = (const char *)__vesacon_format_pixels(rowbuf, src, npixels); + + while (bytes) { + win_off = dst & omask; + win_pos = dst & ~omask; + + if (__unlikely(win_pos != wi.win_pos)) + set_window_pos(win_pos); + + l = min(bytes, win_size - win_off); + memcpy(win_base + win_off, s, l); + + bytes -= l; + s += l; + dst += l; + } +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/vesa.h b/contrib/syslinux-4.02/com32/lib/sys/vesa/vesa.h new file mode 100644 index 0000000..3926c32 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/vesa.h @@ -0,0 +1,114 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#ifndef LIB_SYS_VESA_H +#define LIB_SYS_VESA_H + +#include <inttypes.h> +#include <com32.h> + +/* VESA General Information table */ +struct vesa_general_info { + uint32_t signature; /* Magic number = "VESA" */ + uint16_t version; + far_ptr_t vendor_string; + uint8_t capabilities[4]; + far_ptr_t video_mode_ptr; + uint16_t total_memory; + + uint16_t oem_software_rev; + far_ptr_t oem_vendor_name_ptr; + far_ptr_t oem_product_name_ptr; + far_ptr_t oem_product_rev_ptr; + + uint8_t reserved[222]; + uint8_t oem_data[256]; +} __attribute__ ((packed)); + +#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24)) +#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24)) + +struct vesa_mode_info { + uint16_t mode_attr; + uint8_t win_attr[2]; + uint16_t win_grain; + uint16_t win_size; + uint16_t win_seg[2]; + far_ptr_t win_scheme; + uint16_t logical_scan; + + uint16_t h_res; + uint16_t v_res; + uint8_t char_width; + uint8_t char_height; + uint8_t memory_planes; + uint8_t bpp; + uint8_t banks; + uint8_t memory_layout; + uint8_t bank_size; + uint8_t image_pages; + uint8_t page_function; + + uint8_t rmask; + uint8_t rpos; + uint8_t gmask; + uint8_t gpos; + uint8_t bmask; + uint8_t bpos; + uint8_t resv_mask; + uint8_t resv_pos; + uint8_t dcm_info; + + uint8_t *lfb_ptr; /* Linear frame buffer address */ + uint8_t *offscreen_ptr; /* Offscreen memory address */ + uint16_t offscreen_size; + + uint8_t reserved[206]; +} __attribute__ ((packed)); + +struct vesa_info { + struct vesa_general_info gi; + struct vesa_mode_info mi; +}; + +extern struct vesa_info __vesa_info; + +#if 0 +static inline void vesa_debug(uint32_t color, int pos) +{ + uint32_t *stp = (uint32_t *) __vesa_info.mi.lfb_ptr; + stp[pos * 3] = color; +} +#else +static inline void vesa_debug(uint32_t color, int pos) +{ + (void)color; + (void)pos; +} +#endif + +#endif /* LIB_SYS_VESA_H */ diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesa/video.h b/contrib/syslinux-4.02/com32/lib/sys/vesa/video.h new file mode 100644 index 0000000..d14494b --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesa/video.h @@ -0,0 +1,97 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#ifndef LIB_SYS_VESA_VIDEO_H +#define LIB_SYS_VESA_VIDEO_H + +#include <stdbool.h> +#include <colortbl.h> +#include "vesa.h" + +#define FONT_MAX_CHARS 256 +#define FONT_MAX_HEIGHT 32 +#define FONT_WIDTH 8 + +#define DEFAULT_VESA_X_SIZE 640 +#define DEFAULT_VESA_Y_SIZE 480 + +#define VIDEO_BORDER 8 +#define TEXT_PIXEL_ROWS (__vesa_info.mi.v_res - 2*VIDEO_BORDER) +#define TEXT_PIXEL_COLS (__vesa_info.mi.h_res - 2*VIDEO_BORDER) + +typedef uint16_t attr_t; + +struct vesa_char { + uint8_t ch; /* Character */ + uint8_t _filler; /* Currently unused */ + attr_t attr; /* Color table index */ +}; + +/* Pixel formats in order of decreasing preference; PXF_NONE should be last */ +/* BGR24 is preferred over BGRA32 since the I/O overhead is smaller. */ +enum vesa_pixel_format { + PXF_BGR24, /* 24-bit BGR */ + PXF_BGRA32, /* 32-bit BGRA */ + PXF_LE_RGB16_565, /* 16-bit littleendian 5:6:5 RGB */ + PXF_LE_RGB15_555, /* 15-bit littleendian 5:5:5 RGB */ + PXF_NONE +}; +extern enum vesa_pixel_format __vesacon_pixel_format; +extern unsigned int __vesacon_bytes_per_pixel; +typedef const void *(*__vesacon_format_pixels_t) + (void *, const uint32_t *, size_t); +extern __vesacon_format_pixels_t __vesacon_format_pixels; +extern const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE]; + +extern struct vesa_char *__vesacon_text_display; + +extern int __vesacon_font_height; +extern int __vesacon_text_rows; +extern int __vesacon_text_cols; +extern uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT]; +extern uint32_t *__vesacon_background; +extern uint32_t *__vesacon_shadowfb; + +extern const uint16_t __vesacon_srgb_to_linear[256]; +extern const uint8_t __vesacon_linear_to_srgb[4080]; + +int __vesacon_init_background(void); +int vesacon_load_background(const char *); +int __vesacon_init(int, int); +void __vesacon_init_cursor(int); +void __vesacon_erase(int, int, int, int, attr_t); +void __vesacon_scroll_up(int, attr_t); +void __vesacon_write_char(int, int, uint8_t, attr_t); +void __vesacon_redraw_text(void); +void __vesacon_doit(void); +void __vesacon_set_cursor(int, int, bool); +void __vesacon_copy_to_screen(size_t, const uint32_t *, size_t); +void __vesacon_init_copy_to_screen(void); + +int __vesacon_i915resolution(int x, int y); + +#endif /* LIB_SYS_VESA_VIDEO_H */ diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesacon_write.c b/contrib/syslinux-4.02/com32/lib/sys/vesacon_write.c new file mode 100644 index 0000000..3769317 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesacon_write.c @@ -0,0 +1,194 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved + * Copyright 2009 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * vesacon_write.c + * + * Write to the screen using ANSI control codes (about as capable as + * DOS' ANSI.SYS.) + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <colortbl.h> +#include <console.h> +#include <klibc/compiler.h> +#include <syslinux/config.h> +#include "ansi.h" +#include "file.h" +#include "vesa/video.h" + +static void vesacon_erase(const struct term_state *, int, int, int, int); +static void vesacon_write_char(int, int, uint8_t, const struct term_state *); +static void vesacon_showcursor(const struct term_state *); +static void vesacon_setcursor(int x, int y, bool visible); +static void vesacon_scroll_up(const struct term_state *); + +static struct term_state ts; +static struct ansi_ops op = { + .erase = vesacon_erase, + .write_char = vesacon_write_char, + .showcursor = vesacon_showcursor, + .set_cursor = vesacon_setcursor, + .scroll_up = vesacon_scroll_up, + .beep = __ansicon_beep, +}; + +static struct term_info ti = { + .disabled = 0, + .ts = &ts, + .op = &op +}; + +/* Reference counter to the screen, to keep track of if we need + reinitialization. */ +static int vesacon_counter = 0; + +static struct { + int x, y; +} vesacon_resolution = { + .x = DEFAULT_VESA_X_SIZE, + .y = DEFAULT_VESA_Y_SIZE, +}; + +/* Set desired resolution - requires a full close/open cycle */ +void vesacon_set_resolution(int x, int y) +{ + vesacon_resolution.x = x; + vesacon_resolution.y = y; +} + +/* Common setup */ +int __vesacon_open(struct file_info *fp) +{ + (void)fp; + + if (!vesacon_counter) { + /* Are we disabled? */ + if (syslinux_serial_console_info()->flowctl & 0x8000) { + ti.disabled = 1; + ti.rows = 25; + ti.cols = 80; + } else { + /* Switch mode */ + if (__vesacon_init(vesacon_resolution.x, vesacon_resolution.y)) { + vesacon_counter = -1; + return EAGAIN; + } + + /* Initial state */ + __ansi_init(&ti); + ti.rows = __vesacon_text_rows; + ti.cols = __vesacon_text_cols; + } + } else if (vesacon_counter == -1) { + return EAGAIN; + } + + fp->o.rows = ti.rows; + fp->o.cols = ti.cols; + + vesacon_counter++; + return 0; +} + +int __vesacon_close(struct file_info *fp) +{ + (void)fp; + + vesacon_counter--; + return 0; +} + +/* Erase a region of the screen */ +static void vesacon_erase(const struct term_state *st, + int x0, int y0, int x1, int y1) +{ + __vesacon_erase(x0, y0, x1, y1, st->cindex); +} + +/* Draw text on the screen */ +static void vesacon_write_char(int x, int y, uint8_t ch, + const struct term_state *st) +{ + __vesacon_write_char(x, y, ch, st->cindex); +} + +/* Show or hide the cursor */ +static bool cursor_enabled = true; +void vesacon_cursor_enable(bool enabled) +{ + cursor_enabled = enabled; +} +static void vesacon_showcursor(const struct term_state *st) +{ + vesacon_setcursor(st->xy.x, st->xy.y, st->cursor); +} +static void vesacon_setcursor(int x, int y, bool visible) +{ + __vesacon_set_cursor(x, y, visible && cursor_enabled); +} + +static void vesacon_scroll_up(const struct term_state *st) +{ + __vesacon_scroll_up(1, st->cindex); +} + +ssize_t __vesacon_write(struct file_info *fp, const void *buf, size_t count) +{ + const unsigned char *bufp = buf; + size_t n = 0; + + (void)fp; + + if (ti.disabled) + return count; /* Nothing to do */ + + /* This only updates the shadow text buffer... */ + while (count--) { + __ansi_putchar(&ti, *bufp++); + n++; + } + + /* This actually draws it */ + __vesacon_doit(); + + return n; +} + +const struct output_dev dev_vesacon_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_OUTPUT, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __vesacon_write, + .close = __vesacon_close, + .open = __vesacon_open, + .fallback = &dev_ansicon_w, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/vesaserial_write.c b/contrib/syslinux-4.02/com32/lib/sys/vesaserial_write.c new file mode 100644 index 0000000..775ca19 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/vesaserial_write.c @@ -0,0 +1,61 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * vesaserial_write.c + * + * Write to both to the VESA console and the serial port + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <console.h> +#include "file.h" + +extern int __vesacon_open(struct file_info *); +extern int __vesacon_close(struct file_info *); +extern ssize_t __vesacon_write(struct file_info *, const void *, size_t); +extern ssize_t __xserial_write(struct file_info *, const void *, size_t); + +static ssize_t __vesaserial_write(struct file_info *fp, const void *buf, + size_t count) +{ + __vesacon_write(fp, buf, count); + return __xserial_write(fp, buf, count); +} + +const struct output_dev dev_vesaserial_w = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_TTY | __DEV_OUTPUT, + .fileflags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, + .write = __vesaserial_write, + .close = __vesacon_close, + .open = __vesacon_open, + .fallback = &dev_ansiserial_w, +}; diff --git a/contrib/syslinux-4.02/com32/lib/sys/write.c b/contrib/syslinux-4.02/com32/lib/sys/write.c new file mode 100644 index 0000000..7961fd2 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/write.c @@ -0,0 +1,51 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * write.c + * + * Write to a file descriptor + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <klibc/compiler.h> +#include "file.h" + +ssize_t write(int fd, void *buf, size_t count) +{ + struct file_info *fp = &__file_info[fd]; + + if (fd >= NFILES || !fp->oop) { + errno = EBADF; + return -1; + } + + return fp->oop->write(fp, buf, count); +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/x86_init_fpu.c b/contrib/syslinux-4.02/com32/lib/sys/x86_init_fpu.c new file mode 100644 index 0000000..cf33693 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/x86_init_fpu.c @@ -0,0 +1,58 @@ +/* + * x86_has_fpu.c + * + * Test for an x86 FPU, and do any necessary setup. + */ + +#include <inttypes.h> +#include <sys/fpu.h> + +static inline uint64_t get_cr0(void) +{ + uint32_t v; +asm("movl %%cr0,%0":"=r"(v)); + return v; +} + +static inline void set_cr0(uint32_t v) +{ + asm volatile ("movl %0,%%cr0"::"r" (v)); +} + +#define CR0_PE 0x00000001 +#define CR0_MP 0x00000002 +#define CR0_EM 0x00000004 +#define CR0_TS 0x00000008 +#define CR0_ET 0x00000010 +#define CR0_NE 0x00000020 +#define CR0_WP 0x00010000 +#define CR0_AM 0x00040000 +#define CR0_NW 0x20000000 +#define CR0_CD 0x40000000 +#define CR0_PG 0x80000000 + +int x86_init_fpu(void) +{ + uint32_t cr0; + uint16_t fsw = 0xffff; + uint16_t fcw = 0xffff; + + cr0 = get_cr0(); + cr0 &= ~(CR0_EM | CR0_TS); + cr0 |= CR0_MP; + set_cr0(cr0); + + asm volatile ("fninit"); + asm volatile ("fnstsw %0":"+m" (fsw)); + if (fsw != 0) + return -1; + + asm volatile ("fnstcw %0":"+m" (fcw)); + if ((fcw & 0x103f) != 0x3f) + return -1; + + /* Techically, this could be a 386 with a 287. We could add a check + for that here... */ + + return 0; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/xserial_write.c b/contrib/syslinux-4.02/com32/lib/sys/xserial_write.c new file mode 100644 index 0000000..e399f5f --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/xserial_write.c @@ -0,0 +1,118 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2004-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * xserial_write.c + * + * Raw writing to the serial port; \n -> \r\n translation, and + * convert \1# sequences. + */ + +#include <errno.h> +#include <string.h> +#include <com32.h> +#include <minmax.h> +#include <colortbl.h> +#include <syslinux/config.h> +#include "file.h" + +static void emit(char ch) +{ + static com32sys_t ireg; /* Zeroed with the BSS */ + + ireg.eax.b[1] = 0x04; + ireg.edx.b[0] = ch; + + __intcall(0x21, &ireg, NULL); +} + +ssize_t __xserial_write(struct file_info *fp, const void *buf, size_t count) +{ + const char *bufp = buf; + size_t n = 0; + static enum { st_init, st_tbl, st_tblc } state = st_init; + static int ndigits; + static int ncolor = 0; + int num; + const char *p; + + (void)fp; + + if (!syslinux_serial_console_info()->iobase) + return count; /* Nothing to do */ + + while (count--) { + unsigned char ch = *bufp++; + + switch (state) { + case st_init: + if (ch >= 1 && ch <= 5) { + state = st_tbl; + ndigits = ch; + } else if (ch == '\n') { + emit('\r'); + emit('\n'); + } else { + emit(ch); + } + break; + + case st_tbl: + if (ch == '#') { + state = st_tblc; + ncolor = 0; + } else { + state = st_init; + } + break; + + case st_tblc: + num = ch - '0'; + if (num < 10) { + ncolor = (ncolor * 10) + num; + if (--ndigits == 0) { + if (ncolor < console_color_table_size) { + emit('\033'); + emit('['); + emit('0'); + emit(';'); + for (p = console_color_table[ncolor].ansi; *p; p++) + emit(*p); + emit('m'); + } + state = st_init; + } + } else { + state = st_init; + } + break; + } + n++; + } + + return n; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/zeroregs.c b/contrib/syslinux-4.02/com32/lib/sys/zeroregs.c new file mode 100644 index 0000000..6d52492 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/zeroregs.c @@ -0,0 +1,5 @@ +#include <com32.h> + +/* When we don't need to pass any registers, it's convenient to just + be able to pass a prepared all-zero structure. */ +const com32sys_t __com32_zero_regs; diff --git a/contrib/syslinux-4.02/com32/lib/sys/zfile.c b/contrib/syslinux-4.02/com32/lib/sys/zfile.c new file mode 100644 index 0000000..0e6ba91 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/zfile.c @@ -0,0 +1,171 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2003-2008 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> +#include <syslinux/zio.h> + +#include "file.h" +#include "zlib.h" + +/* + * zopen.c + * + * Open an ordinary file, possibly compressed; if so, insert + * an appropriate decompressor. + */ + +int __file_get_block(struct file_info *fp); +int __file_close(struct file_info *fp); + +static ssize_t gzip_file_read(struct file_info *, void *, size_t); +static int gzip_file_close(struct file_info *); + +static const struct input_dev gzip_file_dev = { + .dev_magic = __DEV_MAGIC, + .flags = __DEV_FILE | __DEV_INPUT, + .fileflags = O_RDONLY, + .read = gzip_file_read, + .close = gzip_file_close, + .open = NULL, +}; + +static int gzip_file_init(struct file_info *fp) +{ + z_streamp zs = calloc(1, sizeof(z_stream)); + + if (!zs) + return -1; + + fp->i.pvt = zs; + + zs->next_in = (void *)fp->i.datap; + zs->avail_in = fp->i.nbytes; + + if (inflateInit2(zs, 15 + 32) != Z_OK) { + errno = EIO; + return -1; + } + + fp->iop = &gzip_file_dev; + fp->i.fd.size = -1; /* Unknown */ + + return 0; +} + +static ssize_t gzip_file_read(struct file_info *fp, void *ptr, size_t n) +{ + z_streamp zs = fp->i.pvt; + int rv; + ssize_t bytes; + ssize_t nout = 0; + unsigned char *p = ptr; + + while (n) { + zs->next_out = p; + zs->avail_out = n; + + if (!zs->avail_in && fp->i.fd.handle) { + if (__file_get_block(fp)) + return nout ? nout : -1; + + zs->next_in = (void *)fp->i.datap; + zs->avail_in = fp->i.nbytes; + } + + rv = inflate(zs, Z_SYNC_FLUSH); + + bytes = n - zs->avail_out; + nout += bytes; + p += bytes; + n -= bytes; + + switch (rv) { + case Z_DATA_ERROR: + case Z_NEED_DICT: + case Z_BUF_ERROR: + case Z_STREAM_ERROR: + default: + errno = EIO; + return nout ? nout : -1; + case Z_MEM_ERROR: + errno = ENOMEM; + return nout ? nout : -1; + case Z_STREAM_END: + return nout; + case Z_OK: + break; + } + } + + return nout; +} + +static int gzip_file_close(struct file_info *fp) +{ + z_streamp zs = fp->i.pvt; + + inflateEnd(zs); + free(zs); + return __file_close(fp); +} + +int zopen(const char *pathname, int flags, ...) +{ + int fd, rv; + struct file_info *fp; + + /* We don't actually give a hoot about the creation bits... */ + fd = open(pathname, flags, 0); + + if (fd < 0) + return -1; + + fp = &__file_info[fd]; + + /* Need to get the first block into the buffer, but not consumed */ + if (__file_get_block(fp)) + goto err; + + if (fp->i.nbytes >= 14 && + (uint8_t) fp->i.buf[0] == 037 && + (uint8_t) fp->i.buf[1] == 0213 && /* gzip */ + fp->i.buf[2] == 8) /* deflate */ + rv = gzip_file_init(fp); + else + rv = 0; /* Plain file */ + + if (!rv) + return fd; + +err: + close(fd); + return -1; +} diff --git a/contrib/syslinux-4.02/com32/lib/sys/zfopen.c b/contrib/syslinux-4.02/com32/lib/sys/zfopen.c new file mode 100644 index 0000000..752aaf4 --- /dev/null +++ b/contrib/syslinux-4.02/com32/lib/sys/zfopen.c @@ -0,0 +1,44 @@ +/* + * zfopen.c + */ + +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <syslinux/zio.h> + +FILE *zfopen(const char *file, const char *mode) +{ + int flags = O_RDONLY; + int plus = 0; + int fd; + + while (*mode) { + switch (*mode) { + case 'r': + flags = O_RDONLY; + break; + case 'w': + flags = O_WRONLY | O_CREAT | O_TRUNC; + break; + case 'a': + flags = O_WRONLY | O_CREAT | O_APPEND; + break; + case '+': + plus = 1; + break; + } + mode++; + } + + if (plus) { + flags = (flags & ~(O_RDONLY | O_WRONLY)) | O_RDWR; + } + + fd = zopen(file, flags, 0666); + + if (fd < 0) + return NULL; + else + return fdopen(fd, mode); +} |