Implement serial on IEEE1275 and EFI.

* docs/grub.texi (Platform-specific limitations): Fix the columen video
	on emu. Mention arc and emu as the only platforms without serial
	support.
	* grub-core/Makefile.core.def (serial): Enable on all terminfomodule and
	ieee1275 platforms.
	* grub-core/term/efi/serial.c: New file.
	* grub-core/term/ieee1275/serial.c: Likewise.
	* grub-core/term/serial.c (grub_serial_find): Disable direct port
	specification if no ns8250 driver is available.
	(grub_cmd_serial): Likewise.
	(GRUB_MOD_INIT) [GRUB_MACHINE_IEEE1275]: Init ofserial.
	(GRUB_MOD_INIT) [GRUB_MACHINE_EFI]: Init efiserial.
	* include/grub/efi/api.h (GRUB_EFI_SERIAL_IO_GUID): New define.
	(grub_efi_parity_type_t): New type.
	(grub_efi_stop_bits_t): Likewise.
	(grub_efi_serial_io_interface): New struct.
	* include/grub/serial.h (grub_serial_port): Make 'broken' field
	available for all interfaces.
	Add EFI and IEEE1275 fields.
	(grub_ofserial_init): New proto.
	(grub_efiserial_init): Likeiwse.
	* util/grub.d/00_header.in: Don't check for the presence of serial
	module.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-02-26 17:08:11 +01:00
parent 0ec820904e
commit a9c7fd1c6c
9 changed files with 566 additions and 19 deletions

View file

@ -1,3 +1,31 @@
2012-02-25 Vladimir Serbinenko <phcoder@gmail.com>
Implement serial on IEEE1275 and EFI.
* docs/grub.texi (Platform-specific limitations): Fix the columen video
on emu. Mention arc and emu as the only platforms without serial
support.
* grub-core/Makefile.core.def (serial): Enable on all terminfomodule and
ieee1275 platforms.
* grub-core/term/efi/serial.c: New file.
* grub-core/term/ieee1275/serial.c: Likewise.
* grub-core/term/serial.c (grub_serial_find): Disable direct port
specification if no ns8250 driver is available.
(grub_cmd_serial): Likewise.
(GRUB_MOD_INIT) [GRUB_MACHINE_IEEE1275]: Init ofserial.
(GRUB_MOD_INIT) [GRUB_MACHINE_EFI]: Init efiserial.
* include/grub/efi/api.h (GRUB_EFI_SERIAL_IO_GUID): New define.
(grub_efi_parity_type_t): New type.
(grub_efi_stop_bits_t): Likewise.
(grub_efi_serial_io_interface): New struct.
* include/grub/serial.h (grub_serial_port): Make 'broken' field
available for all interfaces.
Add EFI and IEEE1275 fields.
(grub_ofserial_init): New proto.
(grub_efiserial_init): Likeiwse.
* util/grub.d/00_header.in: Don't check for the presence of serial
module.
2012-02-25 Vladimir Serbinenko <phcoder@gmail.com> 2012-02-25 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/disk/ieee1275/ofdisk.c (scan): Fix improper use of device * grub-core/disk/ieee1275/ofdisk.c (scan): Fix improper use of device

View file

@ -4105,6 +4105,9 @@ ARC platform is unable to change datetime (firmware doesn't seem to provide a
function for it). function for it).
EMU has similar limitation. EMU has similar limitation.
ARC platform no serial port is available.
EMU has similar limitation.
Console charset refers only to firmware-assisted console. gfxterm is always Console charset refers only to firmware-assisted console. gfxterm is always
Unicode (see Internationalisation section for its limitations). Serial is Unicode (see Internationalisation section for its limitations). Serial is
configurable to UTF-8 or ASCII (see Internationalisation). In case of qemu configurable to UTF-8 or ASCII (see Internationalisation). In case of qemu
@ -4149,7 +4152,6 @@ and mips-qemu_mips can use only memory up to first hole.
@item video @tab yes @tab yes @tab yes @tab yes @item video @tab yes @tab yes @tab yes @tab yes
@item console charset @tab CP437 @tab CP437 @tab CP437 @tab CP437 @item console charset @tab CP437 @tab CP437 @tab CP437 @tab CP437
@item network @tab yes (*) @tab no @tab no @tab no @item network @tab yes (*) @tab no @tab no @tab no
@item serial @tab yes @tab yes @tab yes @tab yes
@item ATA/AHCI @tab yes @tab yes @tab yes @tab yes @item ATA/AHCI @tab yes @tab yes @tab yes @tab yes
@item AT keyboard @tab yes @tab yes @tab yes @tab yes @item AT keyboard @tab yes @tab yes @tab yes @tab yes
@item USB @tab yes @tab yes @tab yes @tab yes @item USB @tab yes @tab yes @tab yes @tab yes
@ -4167,7 +4169,6 @@ and mips-qemu_mips can use only memory up to first hole.
@item video @tab yes @tab yes @tab no @tab no @item video @tab yes @tab yes @tab no @tab no
@item console charset @tab Unicode @tab Unicode @tab ASCII @tab Unicode @item console charset @tab Unicode @tab Unicode @tab ASCII @tab Unicode
@item network @tab yes @tab yes @tab yes @tab yes @item network @tab yes @tab yes @tab yes @tab yes
@item serial @tab yes @tab yes @tab yes @tab no
@item ATA/AHCI @tab yes @tab yes @tab yes @tab no @item ATA/AHCI @tab yes @tab yes @tab yes @tab no
@item AT keyboard @tab yes @tab yes @tab yes @tab no @item AT keyboard @tab yes @tab yes @tab yes @tab no
@item USB @tab yes @tab yes @tab yes @tab no @item USB @tab yes @tab yes @tab yes @tab no
@ -4185,7 +4186,6 @@ and mips-qemu_mips can use only memory up to first hole.
@item video @tab yes @tab no @tab yes @tab no @item video @tab yes @tab no @tab yes @tab no
@item console charset @tab N/A @tab ASCII @tab ASCII @tab ASCII @item console charset @tab N/A @tab ASCII @tab ASCII @tab ASCII
@item network @tab no @tab yes (*) @tab yes @tab no @item network @tab no @tab yes (*) @tab yes @tab no
@item serial @tab yes @tab no @tab no @tab no
@item ATA/AHCI @tab yes @tab no @tab no @tab no @item ATA/AHCI @tab yes @tab no @tab no @tab no
@item AT keyboard @tab yes @tab no @tab no @tab no @item AT keyboard @tab yes @tab no @tab no @tab no
@item USB @tab yes @tab no @tab no @tab no @item USB @tab yes @tab no @tab no @tab no
@ -4200,10 +4200,9 @@ and mips-qemu_mips can use only memory up to first hole.
@multitable @columnfractions .20 .20 .20 .20 .20 @multitable @columnfractions .20 .20 .20 .20 .20
@item @tab MIPS qemu @tab emu @item @tab MIPS qemu @tab emu
@item video @tab no @tab no @item video @tab no @tab yes
@item console charset @tab CP437 @tab ASCII @item console charset @tab CP437 @tab ASCII
@item network @tab no @tab yes @item network @tab no @tab yes
@item serial @tab yes @tab no
@item ATA/AHCI @tab yes @tab no @item ATA/AHCI @tab yes @tab no
@item AT keyboard @tab yes @tab no @item AT keyboard @tab yes @tab no
@item USB @tab N/A @tab yes @item USB @tab N/A @tab yes

View file

@ -1528,8 +1528,11 @@ module = {
name = serial; name = serial;
common = term/serial.c; common = term/serial.c;
x86 = term/ns8250.c; x86 = term/ns8250.c;
ieee1275 = term/ieee1275/serial.c;
efi = term/efi/serial.c;
enable = x86; enable = terminfomodule;
enable = ieee1275;
}; };
module = { module = {

186
grub-core/term/efi/serial.c Normal file
View file

@ -0,0 +1,186 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008,2012 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/disk.h>
#include <grub/partition.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/err.h>
#include <grub/term.h>
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/efi/disk.h>
#include <grub/serial.h>
#include <grub/types.h>
#include <grub/i18n.h>
/* GUID. */
static grub_efi_guid_t serial_io_guid = GRUB_EFI_SERIAL_IO_GUID;
static void
do_real_config (struct grub_serial_port *port)
{
grub_efi_status_t status = GRUB_EFI_SUCCESS;
const grub_efi_parity_type_t parities[] = {
[GRUB_SERIAL_PARITY_NONE] = GRUB_EFI_SERIAL_NO_PARITY,
[GRUB_SERIAL_PARITY_ODD] = GRUB_EFI_SERIAL_ODD_PARITY,
[GRUB_SERIAL_PARITY_EVEN] = GRUB_EFI_SERIAL_EVEN_PARITY
};
const grub_efi_stop_bits_t stop_bits[] = {
[GRUB_SERIAL_STOP_BITS_1] = GRUB_EFI_SERIAL_1_STOP_BIT,
[GRUB_SERIAL_STOP_BITS_2] = GRUB_EFI_SERIAL_2_STOP_BITS,
};
if (port->configured)
return;
status = efi_call_7 (port->interface->set_attributes, port->interface,
port->config.speed,
0, 0, parities[port->config.parity],
port->config.word_len,
stop_bits[port->config.stop_bits]);
if (status != GRUB_EFI_SUCCESS)
port->broken = 1;
port->configured = 1;
}
/* Fetch a key. */
static int
serial_hw_fetch (struct grub_serial_port *port)
{
grub_efi_uintn_t bufsize = 1;
char c;
grub_efi_status_t status = GRUB_EFI_SUCCESS;
do_real_config (port);
if (port->broken)
return -1;
status = efi_call_3 (port->interface->read, port->interface, &bufsize, &c);
if (status != GRUB_EFI_SUCCESS || bufsize == 0)
return -1;
return c;
}
/* Put a character. */
static void
serial_hw_put (struct grub_serial_port *port, const int c)
{
grub_efi_uintn_t bufsize = 1;
char c0 = c;
do_real_config (port);
if (port->broken)
return;
efi_call_3 (port->interface->write, port->interface, &bufsize, &c0);
}
/* Initialize a serial device. PORT is the port number for a serial device.
SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
for the device. Likewise, PARITY is the type of the parity and
STOP_BIT_LEN is the length of the stop bit. The possible values for
WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as
macros. */
static grub_err_t
serial_hw_configure (struct grub_serial_port *port,
struct grub_serial_config *config)
{
if (config->parity != GRUB_SERIAL_PARITY_NONE
&& config->parity != GRUB_SERIAL_PARITY_ODD
&& config->parity != GRUB_SERIAL_PARITY_EVEN)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("unsupported serial port parity"));
if (config->stop_bits != GRUB_SERIAL_STOP_BITS_1
&& config->stop_bits != GRUB_SERIAL_STOP_BITS_2)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("unsupported serial port stop bits number"));
if (config->word_len < 5 || config->word_len > 8)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
N_("unsupported serial port word length"));
port->config = *config;
port->configured = 0;
/* FIXME: should check if the serial terminal was found. */
return GRUB_ERR_NONE;
}
struct grub_serial_driver grub_efiserial_driver =
{
.configure = serial_hw_configure,
.fetch = serial_hw_fetch,
.put = serial_hw_put
};
void
grub_efiserial_init (void)
{
grub_efi_uintn_t num_handles;
grub_efi_handle_t *handles;
grub_efi_handle_t *handle;
int num_serial = 0;
grub_err_t err;
/* Find handles which support the disk io interface. */
handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &serial_io_guid,
0, &num_handles);
if (! handles)
return;
/* Make a linked list of devices. */
for (handle = handles; num_handles--; handle++)
{
struct grub_serial_port *port;
struct grub_efi_serial_io_interface *sio;
sio = grub_efi_open_protocol (*handle, &serial_io_guid,
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (! sio)
/* This should not happen... Why? */
continue;
port = grub_zalloc (sizeof (*port));
if (!port)
return;
port->name = grub_malloc (sizeof ("efiXXXXXXXXXXXXXXXXXXXX"));
if (!port->name)
return;
grub_snprintf (port->name, sizeof ("efiXXXXXXXXXXXXXXXXXXXX"),
"efi%d", num_serial++);
port->driver = &grub_efiserial_driver;
port->interface = sio;
err = grub_serial_config_defaults (port);
if (err)
grub_print_error ();
grub_serial_register (port);
}
grub_free (handles);
return;
}

View file

@ -0,0 +1,257 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2012 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/serial.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/time.h>
#include <grub/i18n.h>
struct ofserial_hash_ent
{
char *devpath;
/* Pointer to shortest available name on nodes representing canonical names,
otherwise NULL. */
const char *shortest;
struct ofserial_hash_ent *next;
};
static void
do_real_config (struct grub_serial_port *port)
{
if (port->configured)
return;
grub_ieee1275_open (port->elem->devpath, &port->handle);
port->configured = 1;
}
/* Fetch a key. */
static int
serial_hw_fetch (struct grub_serial_port *port)
{
grub_ssize_t actual;
char c;
do_real_config (port);
grub_ieee1275_read (port->handle, &c, 1, &actual);
if (actual <= 0)
return -1;
return c;
}
/* Put a character. */
static void
serial_hw_put (struct grub_serial_port *port, const int c)
{
grub_ssize_t actual;
char c0 = c;
do_real_config (port);
grub_ieee1275_write (port->handle, &c0, 1, &actual);
}
/* Initialize a serial device. PORT is the port number for a serial device.
SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
for the device. Likewise, PARITY is the type of the parity and
STOP_BIT_LEN is the length of the stop bit. The possible values for
WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as
macros. */
static grub_err_t
serial_hw_configure (struct grub_serial_port *port __attribute__ ((unused)),
struct grub_serial_config *config __attribute__ ((unused)))
{
/* FIXME: no IEEE1275 serial config available. */
return GRUB_ERR_NONE;
}
struct grub_serial_driver grub_ofserial_driver =
{
.configure = serial_hw_configure,
.fetch = serial_hw_fetch,
.put = serial_hw_put
};
#define OFSERIAL_HASH_SZ 8
static struct ofserial_hash_ent *ofserial_hash[OFSERIAL_HASH_SZ];
static int
ofserial_hash_fn (const char *devpath)
{
int hash = 0;
while (*devpath)
hash ^= *devpath++;
return (hash & (OFSERIAL_HASH_SZ - 1));
}
static struct ofserial_hash_ent *
ofserial_hash_find (const char *devpath)
{
struct ofserial_hash_ent *p = ofserial_hash[ofserial_hash_fn(devpath)];
while (p)
{
if (!grub_strcmp (p->devpath, devpath))
break;
p = p->next;
}
return p;
}
static struct ofserial_hash_ent *
ofserial_hash_add_real (char *devpath)
{
struct ofserial_hash_ent *p;
struct ofserial_hash_ent **head = &ofserial_hash[ofserial_hash_fn(devpath)];
p = grub_malloc(sizeof (*p));
if (!p)
return NULL;
p->devpath = devpath;
p->next = *head;
p->shortest = 0;
*head = p;
return p;
}
static struct ofserial_hash_ent *
ofserial_hash_add (char *devpath, char *curcan)
{
struct ofserial_hash_ent *p, *pcan;
p = ofserial_hash_add_real (devpath);
grub_dprintf ("serial", "devpath = %s, canonical = %s\n", devpath, curcan);
if (!curcan)
{
p->shortest = devpath;
return p;
}
pcan = ofserial_hash_find (curcan);
if (!pcan)
pcan = ofserial_hash_add_real (curcan);
else
grub_free (curcan);
if (!pcan)
grub_errno = GRUB_ERR_NONE;
else
{
if (!pcan->shortest
|| grub_strlen (pcan->shortest) > grub_strlen (devpath))
pcan->shortest = devpath;
}
return p;
}
void
grub_ofserial_init (void)
{
auto int dev_iterate_real (struct grub_ieee1275_devalias *alias,
int use_name);
int dev_iterate_real (struct grub_ieee1275_devalias *alias,
int use_name)
{
struct ofserial_hash_ent *op;
if (grub_strcmp (alias->type, "serial") != 0)
return 0;
grub_dprintf ("serial", "serial name = %s, path = %s\n", alias->name,
alias->path);
op = ofserial_hash_find (alias->path);
if (!op)
{
char *name = grub_strdup (use_name ? alias->name : alias->path);
char *can = grub_strdup (alias->path);
if (!name || !can)
{
grub_errno = GRUB_ERR_NONE;
grub_free (name);
grub_free (can);
return 0;
}
op = ofserial_hash_add (name, can);
}
return 0;
}
auto int dev_iterate_alias (struct grub_ieee1275_devalias *alias);
int dev_iterate_alias (struct grub_ieee1275_devalias *alias)
{
return dev_iterate_real (alias, 1);
}
auto int dev_iterate (struct grub_ieee1275_devalias *alias);
int dev_iterate (struct grub_ieee1275_devalias *alias)
{
return dev_iterate_real (alias, 0);
}
unsigned i;
grub_err_t err;
grub_devalias_iterate (dev_iterate_alias);
grub_ieee1275_devices_iterate (dev_iterate);
for (i = 0; i < ARRAY_SIZE (ofserial_hash); i++)
{
static struct ofserial_hash_ent *ent;
for (ent = ofserial_hash[i]; ent; ent = ent->next)
{
struct grub_serial_port *port;
char *ptr;
if (!ent->shortest)
continue;
port = grub_zalloc (sizeof (*port));
if (!port)
return;
port->name = grub_malloc (sizeof ("ieee1275/")
+ grub_strlen (ent->shortest));
port->elem = ent;
if (!port->name)
return;
ptr = grub_stpcpy (port->name, "ieee1275/");
grub_strcpy (ptr, ent->shortest);
port->driver = &grub_ofserial_driver;
err = grub_serial_config_defaults (port);
if (err)
grub_print_error ();
grub_serial_register (port);
}
}
}

View file

@ -22,7 +22,9 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/terminfo.h> #include <grub/terminfo.h>
#if !defined (GRUB_MACHINE_EMU) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__))
#include <grub/cpu/io.h> #include <grub/cpu/io.h>
#endif
#include <grub/extcmd.h> #include <grub/extcmd.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/list.h> #include <grub/list.h>
@ -134,7 +136,7 @@ grub_serial_find (const char *name)
if (grub_strcmp (port->name, name) == 0) if (grub_strcmp (port->name, name) == 0)
break; break;
#ifndef GRUB_MACHINE_EMU #if (defined(__mips__) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU)
if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0 if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0
&& grub_isxdigit (name [sizeof ("port") - 1])) && grub_isxdigit (name [sizeof ("port") - 1]))
{ {
@ -224,7 +226,8 @@ grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args)
err = port->driver->configure (port, &config); err = port->driver->configure (port, &config);
if (err) if (err)
return err; return err;
#ifndef GRUB_MACHINE_EMU #if !defined (GRUB_MACHINE_EMU) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__))
/* Compatibility kludge. */ /* Compatibility kludge. */
if (port->driver == &grub_ns8250_driver) if (port->driver == &grub_ns8250_driver)
{ {
@ -384,9 +387,15 @@ GRUB_MOD_INIT(serial)
&grub_serial_terminfo_input_template, &grub_serial_terminfo_input_template,
sizeof (grub_serial_terminfo_input)); sizeof (grub_serial_terminfo_input));
#ifndef GRUB_MACHINE_EMU #if !defined (GRUB_MACHINE_EMU) && (defined(__mips__) || defined (__i386__) || defined (__x86_64__))
grub_ns8250_init (); grub_ns8250_init ();
#endif #endif
#ifdef GRUB_MACHINE_IEEE1275
grub_ofserial_init ();
#endif
#ifdef GRUB_MACHINE_EFI
grub_efiserial_init ();
#endif
} }
GRUB_MOD_FINI(serial) GRUB_MOD_FINI(serial)

View file

@ -84,6 +84,11 @@
{ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
} }
#define GRUB_EFI_SERIAL_IO_GUID \
{ 0xbb25cf6f, 0xf1d4, 0x11d2, \
{ 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd } \
}
#define GRUB_EFI_SIMPLE_NETWORK_GUID \ #define GRUB_EFI_SIMPLE_NETWORK_GUID \
{ 0xa19832b9, 0xac25, 0x11d3, \ { 0xa19832b9, 0xac25, 0x11d3, \
{ 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
@ -222,6 +227,24 @@ enum
GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT = 8, GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT = 8,
}; };
typedef enum grub_efi_parity_type
{
GRUB_EFI_SERIAL_DEFAULT_PARITY,
GRUB_EFI_SERIAL_NO_PARITY,
GRUB_EFI_SERIAL_EVEN_PARITY,
GRUB_EFI_SERIAL_ODD_PARITY
}
grub_efi_parity_type_t;
typedef enum grub_efi_stop_bits
{
GRUB_EFI_SERIAL_DEFAULT_STOP_BITS,
GRUB_EFI_SERIAL_1_STOP_BIT,
GRUB_EFI_SERIAL_1_5_STOP_BITS,
GRUB_EFI_SERIAL_2_STOP_BITS
}
grub_efi_stop_bits_t;
/* Enumerations. */ /* Enumerations. */
enum grub_efi_timer_delay enum grub_efi_timer_delay
{ {
@ -1065,6 +1088,27 @@ typedef struct grub_efi_configuration_table grub_efi_configuration_table_t;
#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL #define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL
#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL #define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL
struct grub_efi_serial_io_interface
{
grub_efi_uint32_t revision;
void (*reset) (void);
grub_efi_status_t (*set_attributes) (struct grub_efi_serial_io_interface *this,
grub_efi_uint64_t speed,
grub_efi_uint32_t fifo_depth,
grub_efi_uint32_t timeout,
grub_efi_parity_type_t parity,
grub_uint8_t word_len,
grub_efi_stop_bits_t stop_bits);
void (*set_control_bits) (void);
void (*get_control_bits) (void);
grub_efi_status_t (*write) (struct grub_efi_serial_io_interface *this,
grub_efi_uintn_t *buf_size,
void *buffer);
grub_efi_status_t (*read) (struct grub_efi_serial_io_interface *this,
grub_efi_uintn_t *buf_size,
void *buffer);
};
struct grub_efi_simple_input_interface struct grub_efi_simple_input_interface
{ {
grub_efi_status_t grub_efi_status_t

View file

@ -21,10 +21,15 @@
#define GRUB_SERIAL_HEADER 1 #define GRUB_SERIAL_HEADER 1
#include <grub/types.h> #include <grub/types.h>
#if defined(__mips__) || defined (__i386__) || defined (__x86_64__)
#include <grub/cpu/io.h> #include <grub/cpu/io.h>
#endif
#include <grub/usb.h> #include <grub/usb.h>
#include <grub/list.h> #include <grub/list.h>
#include <grub/term.h> #include <grub/term.h>
#ifdef GRUB_MACHINE_IEEE1275
#include <grub/ieee1275/ieee1275.h>
#endif
struct grub_serial_port; struct grub_serial_port;
struct grub_serial_config; struct grub_serial_config;
@ -68,16 +73,16 @@ struct grub_serial_port
struct grub_serial_driver *driver; struct grub_serial_driver *driver;
struct grub_serial_config config; struct grub_serial_config config;
int configured; int configured;
int broken;
/* This should be void *data but since serial is useful as an early console /* This should be void *data but since serial is useful as an early console
when malloc isn't available it's a union. when malloc isn't available it's a union.
*/ */
union union
{ {
struct #if defined(__mips__) || defined (__i386__) || defined (__x86_64__)
{
grub_port_t port; grub_port_t port;
int broken; #endif
};
struct struct
{ {
grub_usb_device_t usbdev; grub_usb_device_t usbdev;
@ -88,6 +93,16 @@ struct grub_serial_port
struct grub_usb_desc_endp *in_endp; struct grub_usb_desc_endp *in_endp;
struct grub_usb_desc_endp *out_endp; struct grub_usb_desc_endp *out_endp;
}; };
#ifdef GRUB_MACHINE_IEEE1275
struct
{
grub_ieee1275_ihandle_t handle;
struct ofserial_hash_ent *elem;
};
#endif
#ifdef GRUB_MACHINE_EFI
struct grub_efi_serial_io_interface *interface;
#endif
}; };
grub_term_output_t term_out; grub_term_output_t term_out;
grub_term_input_t term_in; grub_term_input_t term_in;
@ -142,8 +157,18 @@ grub_serial_config_defaults (struct grub_serial_port *port)
return port->driver->configure (port, &config); return port->driver->configure (port, &config);
} }
#if defined(__mips__) || defined (__i386__) || defined (__x86_64__)
void grub_ns8250_init (void); void grub_ns8250_init (void);
char *grub_serial_ns8250_add_port (grub_port_t port); char *grub_serial_ns8250_add_port (grub_port_t port);
#endif
#ifdef GRUB_MACHINE_IEEE1275
void grub_ofserial_init (void);
#endif
#ifdef GRUB_MACHINE_EFI
void
grub_efiserial_init (void);
#endif
struct grub_serial_port *grub_serial_find (const char *name); struct grub_serial_port *grub_serial_find (const char *name);
extern struct grub_serial_driver grub_ns8250_driver; extern struct grub_serial_driver grub_ns8250_driver;
void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver); void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver);

View file

@ -112,10 +112,6 @@ for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do
done done
if [ "x$serial" = x1 ]; then if [ "x$serial" = x1 ]; then
if ! test -e "${GRUB_PREFIX}/serial.mod" ; then
gettext "Serial terminal not available on this platform." >&2 ; echo >&2; exit 1
fi
if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
grub_warn "$(gettext "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used.")" grub_warn "$(gettext "Requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used.")"
GRUB_SERIAL_COMMAND=serial GRUB_SERIAL_COMMAND=serial