pixel3xl: implement FrameBufferSerialPortLib

Signed-off-by: Ivaylo Ivanov <ivo.ivanov@null.net>
This commit is contained in:
Ivaylo Ivanov 2021-09-01 20:37:40 +03:00
parent c75269db6e
commit 17593939a6
9 changed files with 734 additions and 1 deletions

View File

@ -0,0 +1,41 @@
#ifndef _FRAMEBUFFER_SERIALPORT_LIB_H_
#define _FRAMEBUFFER_SERIALPORT_LIB_H_
typedef struct _FBCON_POSITION {
INTN x;
INTN y;
} FBCON_POSITION, *PFBCON_POSITION;
typedef struct _FBCON_COLOR {
UINTN Foreground;
UINTN Background;
} FBCON_COLOR, *PFBCON_COLOR;
enum FbConMsgType {
/* type for menu */
FBCON_COMMON_MSG = 0,
FBCON_UNLOCK_TITLE_MSG,
FBCON_TITLE_MSG,
FBCON_SUBTITLE_MSG,
/* type for warning */
FBCON_YELLOW_MSG,
FBCON_ORANGE_MSG,
FBCON_RED_MSG,
FBCON_GREEN_MSG,
/* and the select message's background */
FBCON_SELECT_MSG_BG_COLOR,
};
void ResetFb(void);
UINTN
EFIAPI
SerialPortWriteCritical
(
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
);
#endif

View File

@ -0,0 +1,14 @@
#ifndef _FB_COLOR_H_
#define _FB_COLOR_H_
#define FB_BGRA8888_BLACK 0xff000000
#define FB_BGRA8888_WHITE 0xffffffff
#define FB_BGRA8888_CYAN 0xff00ffff
#define FB_BGRA8888_BLUE 0xff0000ff
#define FB_BGRA8888_SILVER 0xffc0c0c0
#define FB_BGRA8888_YELLOW 0xffffff00
#define FB_BGRA8888_ORANGE 0xffffa500
#define FB_BGRA8888_RED 0xffff0000
#define FB_BGRA8888_GREEN 0xff00ff00
#endif

View File

@ -0,0 +1,136 @@
/*
* Copyright (C) 2008 The Android Open Source Project
* 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.
*/
#ifndef _FONT_5x12_DATA_
#define _FONT_5x12_DATA_
#define FONT_WIDTH 5
#define FONT_HEIGHT 12
#define SCALE_FACTOR 2
unsigned font5x12[] = {
0x00000000, 0x00000000,
0x08421080, 0x00020084,
0x00052940, 0x00000000,
0x15f52800, 0x0000295f,
0x1c52f880, 0x00023e94,
0x08855640, 0x0004d542,
0x04528800, 0x000b2725,
0x00021080, 0x00000000,
0x04211088, 0x00821042,
0x10841082, 0x00221108,
0x09575480, 0x00000000,
0x3e420000, 0x00000084,
0x00000000, 0x00223000,
0x3e000000, 0x00000000,
0x00000000, 0x00471000,
0x08844200, 0x00008442,
0x2318a880, 0x00022a31,
0x08429880, 0x000f9084,
0x1108c5c0, 0x000f8444,
0x1c4443e0, 0x00074610,
0x14a62100, 0x000423e9,
0x26d087e0, 0x00074610,
0x1e10c5c0, 0x00074631,
0x088443e0, 0x00010844,
0x1d18c5c0, 0x00074631,
0x3d18c5c0, 0x00074610,
0x08e20000, 0x00471000,
0x08e20000, 0x00223000,
0x02222200, 0x00082082,
0x01f00000, 0x000003e0,
0x20820820, 0x00008888,
0x1108c5c0, 0x00020084,
0x2b98c5c0, 0x000f05b5,
0x2318a880, 0x0008c63f,
0x1d2949e0, 0x0007ca52,
0x0210c5c0, 0x00074421,
0x252949e0, 0x0007ca52,
0x1e1087e0, 0x000f8421,
0x1e1087e0, 0x00008421,
0x0210c5c0, 0x00074639,
0x3f18c620, 0x0008c631,
0x084211c0, 0x00071084,
0x10842380, 0x00032508,
0x0654c620, 0x0008c525,
0x02108420, 0x000f8421,
0x2b5dc620, 0x0008c631,
0x2b59ce20, 0x0008c739,
0x2318c5c0, 0x00074631,
0x1f18c5e0, 0x00008421,
0x2318c5c0, 0x01075631,
0x1f18c5e0, 0x0008c525,
0x1c10c5c0, 0x00074610,
0x084213e0, 0x00021084,
0x2318c620, 0x00074631,
0x1518c620, 0x0002114a,
0x2b18c620, 0x000556b5,
0x08a54620, 0x0008c54a,
0x08a54620, 0x00021084,
0x088443e0, 0x000f8442,
0x0421084e, 0x00e10842,
0x08210420, 0x00084108,
0x1084210e, 0x00e42108,
0x0008a880, 0x00000000,
0x00000000, 0x01f00000,
0x00000104, 0x00000000,
0x20e00000, 0x000b663e,
0x22f08420, 0x0007c631,
0x22e00000, 0x00074421,
0x23e84200, 0x000f4631,
0x22e00000, 0x0007443f,
0x1e214980, 0x00010842,
0x22e00000, 0x1d187a31,
0x26d08420, 0x0008c631,
0x08601000, 0x00071084,
0x10c02000, 0x0c94a108,
0x0a908420, 0x0008a4a3,
0x084210c0, 0x00071084,
0x2ab00000, 0x0008d6b5,
0x26d00000, 0x0008c631,
0x22e00000, 0x00074631,
0x22f00000, 0x0210be31,
0x23e00000, 0x21087a31,
0x26d00000, 0x00008421,
0x22e00000, 0x00074506,
0x04f10800, 0x00064842,
0x23100000, 0x000b6631,
0x23100000, 0x00022951,
0x23100000, 0x000556b5,
0x15100000, 0x0008a884,
0x23100000, 0x1d185b31,
0x11f00000, 0x000f8444,
0x06421098, 0x01821084,
0x08421080, 0x00021084,
0x30421083, 0x00321084,
0x0004d640, 0x00000000,
0x00000000, 0x00000000,
};
#endif

View File

@ -0,0 +1,464 @@
#include <PiDxe.h>
#include <Library/ArmLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/HobLib.h>
#include <Library/SerialPortLib.h>
#include <Resources/font5x12.h>
#include <Resources/FbColor.h>
#include "FrameBufferSerialPortLib.h"
FBCON_POSITION m_Position;
FBCON_POSITION m_MaxPosition;
FBCON_COLOR m_Color;
BOOLEAN m_Initialized = FALSE;
UINTN gWidth = FixedPcdGet32(PcdMipiFrameBufferWidth);
// Reserve half screen for output
UINTN gHeight = FixedPcdGet32(PcdMipiFrameBufferHeight);
UINTN gBpp = FixedPcdGet32(PcdMipiFrameBufferPixelBpp);
// Module-used internal routine
void FbConPutCharWithFactor
(
char c,
int type,
unsigned scale_factor
);
void FbConDrawglyph
(
char *pixels,
unsigned stride,
unsigned bpp,
unsigned *glyph,
unsigned scale_factor
);
void FbConReset(void);
void FbConScrollUp(void);
void FbConFlush(void);
RETURN_STATUS
EFIAPI
SerialPortInitialize
(
VOID
)
{
UINTN InterruptState = 0;
// Prevent dup initialization
if (m_Initialized) return RETURN_SUCCESS;
// Interrupt Disable
InterruptState = ArmGetInterruptState();
ArmDisableInterrupts();
// Reset console
FbConReset();
// Set flag
m_Initialized = TRUE;
if (InterruptState) ArmEnableInterrupts();
return RETURN_SUCCESS;
}
void ResetFb(void)
{
// Clear current screen.
char* Pixels = (void*)FixedPcdGet32(PcdMipiFrameBufferAddress);
UINTN BgColor = FB_BGRA8888_BLACK;
// Set to black color.
for (UINTN i = 0; i < gWidth; i++)
{
for (UINTN j = 0; j < gHeight; j++)
{
BgColor = FB_BGRA8888_BLACK;
// Set pixel bit
for (UINTN p = 0; p < (gBpp / 8); p++)
{
*Pixels = (unsigned char)BgColor;
BgColor = BgColor >> 8;
Pixels++;
}
}
}
}
void FbConReset(void)
{
// Reset position.
m_Position.x = 0;
m_Position.y = 0;
// Calc max position.
m_MaxPosition.x = gWidth / (FONT_WIDTH + 1);
m_MaxPosition.y = (gHeight - 1) / FONT_HEIGHT;
// Reset color.
m_Color.Foreground = FB_BGRA8888_WHITE;
m_Color.Background = FB_BGRA8888_BLACK;
}
void FbConPutCharWithFactor
(
char c,
int type,
unsigned scale_factor
)
{
char* Pixels;
if (!m_Initialized) return;
paint:
if ((unsigned char)c > 127) return;
if ((unsigned char)c < 32)
{
if (c == '\n')
{
goto newline;
}
else if (c == '\r')
{
m_Position.x = 0;
return;
}
else
{
return;
}
}
// Save some space
if (m_Position.x == 0 && (unsigned char)c == ' ' &&
type != FBCON_SUBTITLE_MSG &&
type != FBCON_TITLE_MSG)
return;
BOOLEAN intstate = ArmGetInterruptState();
ArmDisableInterrupts();
Pixels = (void*)FixedPcdGet32(PcdMipiFrameBufferAddress);
Pixels += m_Position.y * ((gBpp / 8) * FONT_HEIGHT * gWidth);
Pixels += m_Position.x * scale_factor * ((gBpp / 8) * (FONT_WIDTH + 1));
FbConDrawglyph(
Pixels,
gWidth,
(gBpp / 8),
font5x12 + (c - 32) * 2,
scale_factor);
m_Position.x++;
if (m_Position.x >= (int)(m_MaxPosition.x / scale_factor)) goto newline;
if (intstate) ArmEnableInterrupts();
return;
newline:
m_Position.y += scale_factor;
m_Position.x = 0;
if (m_Position.y >= m_MaxPosition.y - scale_factor)
{
ResetFb();
FbConFlush();
m_Position.y = 0;
if (intstate) ArmEnableInterrupts();
goto paint;
}
else
{
FbConFlush();
if (intstate) ArmEnableInterrupts();
}
}
void FbConDrawglyph
(
char *pixels,
unsigned stride,
unsigned bpp,
unsigned *glyph,
unsigned scale_factor
)
{
char *bg_pixels = pixels;
unsigned x, y, i, j, k;
unsigned data, temp;
unsigned int fg_color = m_Color.Foreground;
unsigned int bg_color = m_Color.Background;
stride -= FONT_WIDTH * scale_factor;
for (y = 0; y < FONT_HEIGHT / 2; ++y)
{
for (i = 0; i < scale_factor; i++)
{
for (x = 0; x < FONT_WIDTH; ++x)
{
for (j = 0; j < scale_factor; j++)
{
bg_color = m_Color.Background;
for (k = 0; k < bpp; k++)
{
*bg_pixels = (unsigned char)bg_color;
bg_color = bg_color >> 8;
bg_pixels++;
}
}
}
bg_pixels += (stride * bpp);
}
}
for (y = 0; y < FONT_HEIGHT / 2; ++y)
{
for (i = 0; i < scale_factor; i++)
{
for (x = 0; x < FONT_WIDTH; ++x)
{
for (j = 0; j < scale_factor; j++)
{
bg_color = m_Color.Background;
for (k = 0; k < bpp; k++)
{
*bg_pixels = (unsigned char)bg_color;
bg_color = bg_color >> 8;
bg_pixels++;
}
}
}
bg_pixels += (stride * bpp);
}
}
data = glyph[0];
for (y = 0; y < FONT_HEIGHT / 2; ++y)
{
temp = data;
for (i = 0; i < scale_factor; i++)
{
data = temp;
for (x = 0; x < FONT_WIDTH; ++x)
{
if (data & 1)
{
for (j = 0; j < scale_factor; j++)
{
fg_color = m_Color.Foreground;
for (k = 0; k < bpp; k++)
{
*pixels = (unsigned char)fg_color;
fg_color = fg_color >> 8;
pixels++;
}
}
}
else
{
for (j = 0; j < scale_factor; j++)
{
pixels = pixels + bpp;
}
}
data >>= 1;
}
pixels += (stride * bpp);
}
}
data = glyph[1];
for (y = 0; y < FONT_HEIGHT / 2; ++y)
{
temp = data;
for (i = 0; i < scale_factor; i++)
{
data = temp;
for (x = 0; x < FONT_WIDTH; ++x)
{
if (data & 1)
{
for (j = 0; j < scale_factor; j++)
{
fg_color = m_Color.Foreground;
for (k = 0; k < bpp; k++)
{
*pixels = (unsigned char)fg_color;
fg_color = fg_color >> 8;
pixels++;
}
}
}
else
{
for (j = 0; j < scale_factor; j++)
{
pixels = pixels + bpp;
}
}
data >>= 1;
}
pixels += (stride * bpp);
}
}
}
/* TODO: Take stride into account */
void FbConScrollUp(void)
{
unsigned short *dst = (void*)FixedPcdGet32(PcdMipiFrameBufferAddress);
unsigned short *src = dst + (gWidth * FONT_HEIGHT);
unsigned count = gWidth * (gHeight - FONT_HEIGHT);
while (count--)
{
*dst++ = *src++;
}
count = gWidth * FONT_HEIGHT;
while (count--)
{
*dst++ = m_Color.Background;
}
FbConFlush();
}
void FbConFlush(void)
{
unsigned total_x, total_y;
unsigned bytes_per_bpp;
total_x = gWidth;
total_y = gHeight;
bytes_per_bpp = (gBpp / 8);
WriteBackInvalidateDataCacheRange(
(void*)FixedPcdGet32(PcdMipiFrameBufferAddress),
(total_x * total_y * bytes_per_bpp)
);
}
UINTN
EFIAPI
SerialPortWrite
(
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
UINT8* CONST Final = &Buffer[NumberOfBytes];
UINTN InterruptState = ArmGetInterruptState();
ArmDisableInterrupts();
while (Buffer < Final)
{
FbConPutCharWithFactor(*Buffer++, FBCON_COMMON_MSG, SCALE_FACTOR);
}
if (InterruptState) ArmEnableInterrupts();
return NumberOfBytes;
}
UINTN
EFIAPI
SerialPortWriteCritical
(
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
UINT8* CONST Final = &Buffer[NumberOfBytes];
UINTN CurrentForeground = m_Color.Foreground;
UINTN InterruptState = ArmGetInterruptState();
ArmDisableInterrupts();
m_Color.Foreground = FB_BGRA8888_YELLOW;
while (Buffer < Final)
{
FbConPutCharWithFactor(*Buffer++, FBCON_COMMON_MSG, SCALE_FACTOR);
}
m_Color.Foreground = CurrentForeground;
if (InterruptState) ArmEnableInterrupts();
return NumberOfBytes;
}
UINTN
EFIAPI
SerialPortRead
(
OUT UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
return 0;
}
BOOLEAN
EFIAPI
SerialPortPoll
(
VOID
)
{
return FALSE;
}
RETURN_STATUS
EFIAPI
SerialPortSetControl
(
IN UINT32 Control
)
{
return RETURN_UNSUPPORTED;
}
RETURN_STATUS
EFIAPI
SerialPortGetControl
(
OUT UINT32 *Control
)
{
return RETURN_UNSUPPORTED;
}
RETURN_STATUS
EFIAPI
SerialPortSetAttributes
(
IN OUT UINT64 *BaudRate,
IN OUT UINT32 *ReceiveFifoDepth,
IN OUT UINT32 *Timeout,
IN OUT EFI_PARITY_TYPE *Parity,
IN OUT UINT8 *DataBits,
IN OUT EFI_STOP_BITS_TYPE *StopBits
)
{
return RETURN_UNSUPPORTED;
}
UINTN SerialPortFlush(VOID)
{
return 0;
}
VOID
EnableSynchronousSerialPortIO(VOID)
{
// Already synchronous
}

View File

@ -0,0 +1,41 @@
#ifndef _FRAMEBUFFER_SERIALPORT_LIB_H_
#define _FRAMEBUFFER_SERIALPORT_LIB_H_
typedef struct _FBCON_POSITION {
INTN x;
INTN y;
} FBCON_POSITION, *PFBCON_POSITION;
typedef struct _FBCON_COLOR {
UINTN Foreground;
UINTN Background;
} FBCON_COLOR, *PFBCON_COLOR;
enum FbConMsgType {
/* type for menu */
FBCON_COMMON_MSG = 0,
FBCON_UNLOCK_TITLE_MSG,
FBCON_TITLE_MSG,
FBCON_SUBTITLE_MSG,
/* type for warning */
FBCON_YELLOW_MSG,
FBCON_ORANGE_MSG,
FBCON_RED_MSG,
FBCON_GREEN_MSG,
/* and the select message's background */
FBCON_SELECT_MSG_BG_COLOR,
};
void ResetFb(void);
UINTN
EFIAPI
SerialPortWriteCritical
(
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
);
#endif

View File

@ -0,0 +1,30 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = FrameBufferSerialPortLib
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = SerialPortLib
[Sources.common]
FrameBufferSerialPortLib.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
Pixel3XL/Pixel3XL.dec
[LibraryClasses]
ArmLib
PcdLib
IoLib
HobLib
CompilerIntrinsicsLib
CacheMaintenanceLib
[Pcd]
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferAddress
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferWidth
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferHeight
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferPixelBpp
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight

View File

@ -36,4 +36,6 @@
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferAddress|0x00400000|UINT32|0x0000a400 # 0x7C400000
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferWidth|1080|UINT32|0x0000a401
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferHeight|1920|UINT32|0x0000a402
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferPixelBpp|32|UINT32|0x0000a403
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferPixelBpp|24|UINT32|0x0000a403
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth|1080|UINT32|0x0000a404
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight|1920|UINT32|0x0000a405

View File

@ -31,6 +31,7 @@
[LibraryClasses.common]
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmPlatformLib|Pixel3XL/Library/Pixel3XLLib/Pixel3XLLib.inf
CompilerIntrinsicsLib|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
@ -66,6 +67,8 @@
# SimpleFbDxe
FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
SerialPortLib|Pixel3XL/Library/FrameBufferSerialPortLib/FrameBufferSerialPortLib.inf
[LibraryClasses.common.SEC]
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
@ -136,6 +139,8 @@
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferAddress|0x8e000000
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferWidth|720
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferHeight|1280
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth|720
gPixel3XLTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight|1280
gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x20

Binary file not shown.