EFI: Implement console code.
This commit is contained in:
committed by
Jessica Hamilton
parent
bd0604764e
commit
735f1daee9
@@ -18,7 +18,8 @@ local efi_glue_src =
|
||||
|
||||
local platform_src =
|
||||
relocation_func.cpp
|
||||
start.c
|
||||
start.cpp
|
||||
console.cpp
|
||||
;
|
||||
|
||||
Includes [ FGristFiles $(efi_glue_src) $(platform_src) ]
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 2014-2016 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2013 Fredrik Holmqvist, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "console.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <boot/stage2.h>
|
||||
#include <boot/platform.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include "efi_platform.h"
|
||||
|
||||
|
||||
class Console : public ConsoleNode {
|
||||
public:
|
||||
Console();
|
||||
|
||||
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
|
||||
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
|
||||
};
|
||||
|
||||
|
||||
static uint32 sScreenWidth;
|
||||
static uint32 sScreenHeight;
|
||||
static uint32 sScreenMode;
|
||||
static Console sInput, sOutput;
|
||||
FILE *stdin, *stdout, *stderr;
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
Console::Console()
|
||||
: ConsoleNode()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
Console::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer, size_t bufferSize)
|
||||
{
|
||||
const char *string = (const char *)buffer;
|
||||
CHAR16 ucsBuffer[bufferSize + 3];
|
||||
uint32 j = 0;
|
||||
|
||||
for (uint32 i = 0; i < bufferSize; i++) {
|
||||
switch (string[i]) {
|
||||
case '\n': {
|
||||
ucsBuffer[j++] = '\r';
|
||||
ucsBuffer[j++] = '\n';
|
||||
} //fallthrough
|
||||
case 0 : {
|
||||
//Not sure if we should keep going or abort for 0.
|
||||
//Keep going was easy anyway.
|
||||
ucsBuffer[j] = 0;
|
||||
kSystemTable->ConOut->OutputString(kSystemTable->ConOut, ucsBuffer);
|
||||
j = 0;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
ucsBuffer[j++] = (CHAR16) string[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (j > 0) {
|
||||
ucsBuffer[j] = 0;
|
||||
kSystemTable->ConOut->OutputString(kSystemTable->ConOut, ucsBuffer);
|
||||
}
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
void
|
||||
console_clear_screen(void)
|
||||
{
|
||||
kSystemTable->ConOut->ClearScreen(kSystemTable->ConOut);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
console_width(void)
|
||||
{
|
||||
return sScreenWidth;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
console_height(void)
|
||||
{
|
||||
return sScreenHeight;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
console_set_cursor(int32 x, int32 y)
|
||||
{
|
||||
kSystemTable->ConOut->SetCursorPosition(kSystemTable->ConOut, x, y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
console_show_cursor(void)
|
||||
{
|
||||
kSystemTable->ConOut->EnableCursor(kSystemTable->ConOut, true);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
console_hide_cursor(void)
|
||||
{
|
||||
kSystemTable->ConOut->EnableCursor(kSystemTable->ConOut, false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
console_set_color(int32 foreground, int32 background)
|
||||
{
|
||||
kSystemTable->ConOut->SetAttribute(kSystemTable->ConOut,
|
||||
EFI_TEXT_ATTR((foreground & 0xf), (background & 0xf)));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
console_wait_for_key(void)
|
||||
{
|
||||
UINTN index;
|
||||
EFI_STATUS status;
|
||||
EFI_INPUT_KEY key;
|
||||
EFI_EVENT event = kSystemTable->ConIn->WaitForKey;
|
||||
|
||||
do {
|
||||
kBootServices->WaitForEvent(1, &event, &index);
|
||||
status = kSystemTable->ConIn->ReadKeyStroke(kSystemTable->ConIn, &key);
|
||||
} while (status == EFI_NOT_READY);
|
||||
|
||||
if (key.UnicodeChar > 0)
|
||||
return (int) key.UnicodeChar;
|
||||
|
||||
switch (key.ScanCode) {
|
||||
case SCAN_UP:
|
||||
return TEXT_CONSOLE_KEY_UP;
|
||||
case SCAN_DOWN:
|
||||
return TEXT_CONSOLE_KEY_DOWN;
|
||||
case SCAN_LEFT:
|
||||
return TEXT_CONSOLE_KEY_LEFT;
|
||||
case SCAN_RIGHT:
|
||||
return TEXT_CONSOLE_KEY_RIGHT;
|
||||
case SCAN_PAGE_UP:
|
||||
return TEXT_CONSOLE_KEY_PAGE_UP;
|
||||
case SCAN_PAGE_DOWN:
|
||||
return TEXT_CONSOLE_KEY_PAGE_DOWN;
|
||||
case SCAN_HOME:
|
||||
return TEXT_CONSOLE_KEY_HOME;
|
||||
case SCAN_END:
|
||||
return TEXT_CONSOLE_KEY_END;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void update_screen_size(void)
|
||||
{
|
||||
UINTN width, height;
|
||||
UINTN area = 0;
|
||||
SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut = kSystemTable->ConOut;
|
||||
|
||||
for (int mode = 0; mode < ConOut->Mode->MaxMode; ++mode) {
|
||||
if (ConOut->QueryMode(ConOut, mode, &width, &height) == EFI_SUCCESS) {
|
||||
if (width * height > area) {
|
||||
sScreenWidth = width;
|
||||
sScreenHeight = height;
|
||||
sScreenMode = mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConOut->SetMode(ConOut, sScreenMode);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
console_init(void)
|
||||
{
|
||||
update_screen_size();
|
||||
console_hide_cursor();
|
||||
console_clear_screen();
|
||||
|
||||
// enable stdio functionality
|
||||
stdin = (FILE *)&sInput;
|
||||
stdout = stderr = (FILE *)&sOutput;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
platform_switch_to_text_mode(void)
|
||||
{
|
||||
kSystemTable->ConOut->Reset(kSystemTable->ConOut, false);
|
||||
kSystemTable->ConOut->SetMode(kSystemTable->ConOut, sScreenMode);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
|
||||
** Distributed under the terms of the Haiku License.
|
||||
*/
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
|
||||
|
||||
#include <boot/platform/generic/text_console.h>
|
||||
|
||||
|
||||
extern "C" status_t console_init(void);
|
||||
|
||||
|
||||
#endif /* CONSOLE_H */
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2013, Fredrik Homlqvist, [email protected].
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef EFI_PLATFORM_H
|
||||
#define EFI_PLATFORM_H
|
||||
|
||||
|
||||
#include "efibind.h"
|
||||
#include "efidef.h"
|
||||
#include "efidevp.h"
|
||||
#include "efiprot.h"
|
||||
#include "eficon.h"
|
||||
#include "efierr.h"
|
||||
#include "efiapi.h"
|
||||
|
||||
|
||||
extern const EFI_SYSTEM_TABLE *kSystemTable;
|
||||
extern const EFI_BOOT_SERVICES *kBootServices;
|
||||
extern const EFI_RUNTIME_SERVICES *kRuntimeServices;
|
||||
|
||||
|
||||
#endif /* EFI_PLATFORM_H */
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE
|
||||
* COPYRIGHT OWNER 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 "efibind.h"
|
||||
#include "efidef.h"
|
||||
#include "efidevp.h"
|
||||
#include "eficon.h"
|
||||
#include "efiprot.h"
|
||||
#include "efiapi.h"
|
||||
#include "efierr.h"
|
||||
|
||||
static const CHAR16 *exampleText = L"Example EFI Application. Press any key!";
|
||||
|
||||
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable);
|
||||
|
||||
/**
|
||||
* efi_main - The entry point for the EFI application
|
||||
* @image: firmware-allocated handle that identifies the image
|
||||
* @SystemTable: EFI system table
|
||||
*/
|
||||
EFI_STATUS
|
||||
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable)
|
||||
{
|
||||
UINTN index;
|
||||
EFI_EVENT event = systemTable->ConIn->WaitForKey;
|
||||
|
||||
SIMPLE_TEXT_OUTPUT_INTERFACE *conOut = systemTable->ConOut;
|
||||
conOut->OutputString(conOut, (CHAR16*)exampleText);
|
||||
|
||||
systemTable->BootServices->WaitForEvent(1, &event, &index);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2014-2016 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2013 Fredrik Holmqvist, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "efi_platform.h"
|
||||
|
||||
|
||||
extern void (*__ctor_list)(void);
|
||||
extern void (*__ctor_end)(void);
|
||||
|
||||
|
||||
const EFI_SYSTEM_TABLE *kSystemTable;
|
||||
const EFI_BOOT_SERVICES *kBootServices;
|
||||
const EFI_RUNTIME_SERVICES *kRuntimeServices;
|
||||
|
||||
|
||||
static void
|
||||
call_ctors(void)
|
||||
{
|
||||
void (**f)(void);
|
||||
|
||||
for (f = &__ctor_list; f < &__ctor_end; f++)
|
||||
(**f)();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* efi_main - The entry point for the EFI application
|
||||
* @image: firmware-allocated handle that identifies the image
|
||||
* @systemTable: EFI system table
|
||||
*/
|
||||
extern "C" EFI_STATUS
|
||||
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable)
|
||||
{
|
||||
kSystemTable = systemTable;
|
||||
kBootServices = systemTable->BootServices;
|
||||
kRuntimeServices = systemTable->RuntimeServices;
|
||||
|
||||
call_ctors();
|
||||
|
||||
console_init();
|
||||
|
||||
printf("Hello from EFI Loader for Haiku!\nPress any key to continue...\n");
|
||||
console_wait_for_key();
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user