diff -urN grub2.org/include/grub/ieee1275/ieee1275.h grub2/include/grub/ieee1275/ieee1275.h --- grub2.org/include/grub/ieee1275/ieee1275.h 2007-10-04 22:44:12.000000000 +0200 +++ grub2/include/grub/ieee1275/ieee1275.h 2007-10-10 16:41:39.594688149 +0200 @@ -82,6 +82,16 @@ /* CodeGen firmware does not correctly implement "output-device output" */ GRUB_IEEE1275_FLAG_BROKEN_OUTPUT, + + /* In non fb mode default number of console rows is 24, but in fact it's 25 */ + GRUB_IEEE1275_FLAG_NOFB_ROWS25, + + /* Old Pegaos firmware does not accept cls escape sequence */ + GRUB_IEEE1275_FLAG_NOCLS, + + /* On CodeGen firmware, cp437 characters 0xc0 to 0xcb are reserved for the + bplan logo */ + GRUB_IEEE1275_FLAG_BPLAN_LOGO, }; extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff -urN grub2.org/kern/powerpc/ieee1275/cmain.c grub2/kern/powerpc/ieee1275/cmain.c --- grub2.org/kern/powerpc/ieee1275/cmain.c 2007-10-04 22:44:12.000000000 +0200 +++ grub2/kern/powerpc/ieee1275/cmain.c 2007-10-10 16:42:30.520688149 +0200 @@ -73,6 +73,8 @@ { /* Broken in all versions */ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_OUTPUT); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NOFB_ROWS25); + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BPLAN_LOGO); /* There are two incompatible ways of checking the version number. Try both. */ @@ -98,6 +100,13 @@ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0); grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_0_BASED_PARTITIONS); } + /* It seems old firmware for Pegaos 1 do not accept cls escape then + we need to emulate it using \n sequence */ + if (!grub_strcmp (tmp, "1.0") + || !grub_strcmp (tmp, "1.1")) + { + grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NOCLS); + } } } } diff -urN grub2.org/term/ieee1275/ofconsole.c grub2/term/ieee1275/ofconsole.c --- grub2.org/term/ieee1275/ofconsole.c 2007-10-04 22:44:12.000000000 +0200 +++ grub2/term/ieee1275/ofconsole.c 2007-10-10 16:51:56.829688149 +0200 @@ -24,12 +24,18 @@ #include #include +static void grub_ofconsole_setflags(int flags, int x); + static grub_ieee1275_ihandle_t stdout_ihandle; static grub_ieee1275_ihandle_t stdin_ihandle; static grub_uint8_t grub_ofconsole_width; static grub_uint8_t grub_ofconsole_height; +/* We will assume serial console by default */ +static grub_uint8_t grub_ofconsole_fb = 0; +static grub_uint8_t grub_ofconsole_serial = 1; + static int grub_curr_x; static int grub_curr_y; @@ -70,20 +76,76 @@ static void grub_ofconsole_putchar (grub_uint32_t c) { - char chr = c; - - if (c == '\n') + char chr; + + if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BPLAN_LOGO)) { + /* cp437 characters 0xc0 to 0xcb are reserved for the bplan logo. Use + this layout to workaround it: + ╒═╕ + │ │ + ╘═╛ */ + switch (c) + { + case 0xc4: + /* GRUB_TERM_DISP_HLINE */ + c = 0xcd; + break; + case 0xb3: + /* GRUB_TERM_DISP_VLINE */ + c = 0xb3; + break; + case 0xda: + /* GRUB_TERM_DISP_UL */ + c = 0xd5; + break; + case 0xbf: + /* GRUB_TERM_DISP_UR */ + c = 0xb8; + break; + case 0xc0: + /* GRUB_TERM_DISP_LL */ + c = 0xd4; + break; + case 0xd9: + /* GRUB_TERM_DISP_LR */ + c = 0xbe; + break; + } + } + + switch(c) + { + case '\a': + break; + case '\n': + grub_putcode ('\r'); grub_curr_y++; + if(grub_curr_y > (grub_ofconsole_height - 1)) + /* Is this realy correct for all OF versions around ? */ + grub_curr_y = grub_ofconsole_fb ? + grub_curr_y - 4 : grub_ofconsole_height - 1; + break; + case '\r': grub_curr_x = 0; - } - else - { + break; + case '\b': + if(grub_curr_x > 0) + grub_curr_x--; + break; + + default: + if(c == '\t') + c = ' '; + + if (grub_curr_x >= (grub_ofconsole_width - 1)) + grub_putcode ('\n'); + grub_curr_x++; - if (grub_curr_x > grub_ofconsole_width) - grub_putcode ('\n'); - } + break; + } + chr = c; grub_ieee1275_write (stdout_ihandle, &chr, 1, 0); } @@ -228,7 +290,7 @@ static grub_uint16_t grub_ofconsole_getxy (void) { - return ((grub_curr_x - 1) << 8) | grub_curr_y; + return (grub_curr_x << 8) | grub_curr_y; } static grub_uint16_t @@ -278,6 +340,10 @@ if (! grub_ofconsole_height) grub_ofconsole_height = 24; + if ( grub_ofconsole_fb == 0 && grub_ofconsole_serial == 0 && grub_ofconsole_height == 24 && + grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NOFB_ROWS25)) + grub_ofconsole_height = 25; + return (grub_ofconsole_width << 8) | grub_ofconsole_height; } @@ -295,10 +361,20 @@ static void grub_ofconsole_cls (void) { - /* Clear the screen. Using serial console, screen(1) only recognizes the - * ANSI escape sequence. Using video console, Apple Open Firmware (version - * 3.1.1) only recognizes the literal ^L. So use both. */ - grub_ofconsole_writeesc (" \e[2J"); + if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NOCLS)) + { + /* Clear the screen. Using serial console, screen(1) only recognizes the + * ANSI escape sequence. Using video console, Apple Open Firmware (version + * 3.1.1) only recognizes the literal ^L. So use both. */ + grub_ofconsole_writeesc (" \e[2J"); + } + else + { + /* It seems no cls escape is available then simulate it using \n flood */ + int x = (grub_ofconsole_height * 2) - grub_curr_y; + while(x--) + grub_putcode ('\n'); + } grub_gotoxy (0, 0); } @@ -317,6 +393,7 @@ static grub_err_t grub_ofconsole_init (void) { + grub_ieee1275_phandle_t stdout_phandle; unsigned char data[4]; grub_ssize_t actual; int col; @@ -349,6 +426,48 @@ /* Set the right fg and bg colors. */ grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL); + /* Check do we are on serial or normal console */ + if(! grub_ieee1275_instance_to_package (stdout_ihandle, &stdout_phandle)) + { + char type[16]; + char name[128]; + + if(! grub_ieee1275_get_property (stdout_phandle, "device_type", &type, + sizeof type, 0) && + ! grub_ieee1275_get_property (stdout_phandle, "name", &name, + sizeof name, 0)) + { + /* + * In general type "serial" is used for console without + * framebuffer support in recent firmware versions then + * we need to check the name too to determine is it real or + * serial console + */ + + if (! grub_strcmp (type, "serial")) + { + /* If "name" is something else than "display" we assume serial console */ + if(! grub_strcmp (name, "display")) + grub_ofconsole_serial = 0; + } + else + { + grub_ofconsole_serial = 0; + + /* Older versions use name/type set to "bootconsole" */ + if ( grub_strcmp (name, "bootconsole")) + grub_ofconsole_fb = 1; + } + } + } + + /* Set term flags */ + if(!grub_ofconsole_serial && !grub_ofconsole_fb) + { + grub_ofconsole_setflags(GRUB_TERM_SIMPLE_MENU, 0); + grub_ofconsole_setflags(GRUB_TERM_CP437_MENU, 1); + } + return 0; } @@ -377,7 +496,7 @@ .setcolor = grub_ofconsole_setcolor, .setcursor = grub_ofconsole_setcursor, .refresh = grub_ofconsole_refresh, - .flags = GRUB_TERM_SIMPLE_MENU, + .flags = GRUB_TERM_SIMPLE_MENU, /* We are set to serial by default */ .next = 0 }; @@ -393,3 +512,12 @@ { grub_term_unregister (&grub_ofconsole_term); } + +static void +grub_ofconsole_setflags(int flags, int x) +{ + if(x) + grub_ofconsole_term.flags |= flags; + else + grub_ofconsole_term.flags &= ~flags; +}