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 =
|
local platform_src =
|
||||||
relocation_func.cpp
|
relocation_func.cpp
|
||||||
start.c
|
start.cpp
|
||||||
|
console.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
Includes [ FGristFiles $(efi_glue_src) $(platform_src) ]
|
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