RE: [Linux-ia64] efi/elilo serial output

Douglas Johnson
2001-07-30T14:27:38Z

[-- Attachment #1: Type: TEXT/PLAIN, Size: 816 bytes --]

Hi,
We have this problem as well. I think the best solution for this
is to write a program that uses the /proc/efi interface. Another way of
doing this would be to write an EFI program. Attached is a program
fragment that, I think, with some work could set the speed (used code from
libtty from intel efi toolkit). We hope to not just set the speed of the
console output of the kernel but to have POST messages/efi console-
redirection running at a slower speed as well.

Are there any EFI experts who have comments on this? Do the new values in
the SERIAL_IO_MODE structure get updated in nvram so the redirection speed
is preserved across reboots?

Doug

On Fri, 27 Jul 2001, Egan Ford wrote:

> Scratch 57600, it is really 115200. I need to bump it down, most terminal
> servers
> do not get above 38400.
>

[-- Attachment #2: Type: TEXT/PLAIN, Size: 5400 bytes --]

/*
* Copyright (c) 1999, 2000
* Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. All advertising materials mentioning features or use of this software must
* display the following acknowledgement:
*
* This product includes software developed by Intel Corporation and its
* contributors.
*
* 4. Neither the name of Intel Corporation or its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

/*

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>

static int _ttyInterfaces = -1;
static ttyListEntry_t *ttyList = NULL;

/* Fix setserial() to take no arguements (hard code device, speed, etc... /*

EFI_STATUS setserial (char *FilePath, char *DevName, /* Set to device name */
int Flags,
mode_t Mode, EFI_DEVICE_PATH * DevPath, INT32 * fd)
{
SERIAL_IO_INTERFACE *pIface;
wchar_t *wcspath;
EFI_STATUS Status;
ttyListEntry_t *pDev;
ttyInstance_t *ptty;
int i;
EFI_Guid *GUID /* Set BB25CF6F-F1D4-11D2-9A0C-0090273FC1FD */
/*
* Assume the worst
*/
* fd = -1;

/*
* Find the tty in question
*/
for (pDev = ttyList, i = 0; i < _ttyInterfaces; i++, pDev++)
{
if (strcmp (DevName, pDev->ttyName) == 0)
{
break;
}
}

if (i == _ttyInterfaces)
return (EFI_INVALID_PARAMETER);

/*
* Allocate a tty instance
*/
ptty = malloc (sizeof (ttyInstance_t));
if (ptty == NULL)
return (EFI_OUT_OF_RESOURCES);

pDev->ModemControl =
EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY;
ptty->Dev = pDev;
pIface = pDev->pIface;

/*
* Convert path to UNICODE
*/
if (FilePath)
{
wcspath = calloc (strlen (FilePath) + 1, sizeof (wchar_t));
if (wcspath == NULL)
{
free (ptty);
return (EFI_OUT_OF_RESOURCES);
}
mbstowcs (wcspath, FilePath, strlen (FilePath) + 1);
}
else
{
wcspath = L"";
}

/*
* Reset the port if this is the first open
*/
if (pDev->InUse == 0)
{
Status = pIface->Reset (pIface);
}
else
{
Status = EFI_SUCCESS;
}
if (!EFI_ERROR (Status))
{
SERIAL_IO_MODE *pMode = pIface->Mode;

Status = pIface->SetAttributes (pIface, pMode->BaudRate, 15,
/*
* The timeout MUST be at least as long as it
* takes to send a single character or we will
* always get a timeout when sending more than
* two characters. The +10 is a fudge factor.
*/
UsecPerChar (pMode->BaudRate) + 10,
pMode->Parity,
(UINT8) pMode->DataBits,
pMode->StopBits);

/* Set desired values for baud rate here. */

if (!EFI_ERROR (Status))
{
pDev->termios.c_cflag = Efi2cflags (pMode);
pDev->termios.c_cc[VTIME] = (cc_t) (pMode->Timeout / (1000 * 100));
pDev->termios.c_cc[VMIN] = 1;
pDev->termios.c_ispeed = (speed_t) pMode->BaudRate;
pDev->termios.c_ospeed = (speed_t) pMode->BaudRate;

/*
* Initialize the termios defaults if first open
*/
if (pDev->InUse == 0)
{
pDev->termios.c_iflag = DEFAULT_TERMIOS_IFLAG;
pDev->termios.c_oflag = DEFAULT_TERMIOS_OFLAG;
pDev->termios.c_lflag = DEFAULT_TERMIOS_LFLAG;

Status = pIface->SetControl (pIface, pDev->ModemControl);
}
}
}

if (EFI_ERROR (Status))
free (ptty);

return (Status);
}

EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE * systab)
{
EFI_STATUS status;
CHAR16 name[256], *val, fmt[20];
EFI_GUID vendor;
UINTN size;

Print (W2U (L"Setting Baud rate of serial 1.\n"));
status = setserial ();
if (EFI_ERROR (status))
{
Print (W2U (L"setserial failed.\n"));
}
else
Print (W2U (L"setserial completed.\n"));

return EFI_SUCCESS;
}