mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 02:48:37 +08:00
arch/x86_64/intel64: add support for framebuffer
arch/x86_64/intel64: add support for framebuffer Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
This commit is contained in:
parent
547cbf3ba6
commit
bb98911a11
8 changed files with 388 additions and 6 deletions
|
@ -147,6 +147,34 @@ config MULTBOOT2_FB_TERM
|
|||
---help---
|
||||
Enable a framebuffer terminal for early debug printing
|
||||
|
||||
config MULTBOOT2_FB
|
||||
bool "Multiboot2 framebuffer"
|
||||
default n
|
||||
---help---
|
||||
Enable a framebuffer support
|
||||
|
||||
if MULTBOOT2_FB
|
||||
|
||||
config MULTBOOT2_FB_WIDTH
|
||||
int "Multiboot2 framebuffer width"
|
||||
default 1024
|
||||
---help---
|
||||
Requested framebuffer width
|
||||
|
||||
config MULTBOOT2_FB_HEIGHT
|
||||
int "Multiboot2 framebuffer height"
|
||||
default 768
|
||||
---help---
|
||||
Requested framebuffer height
|
||||
|
||||
config MULTBOOT2_FB_DEEPTH
|
||||
int "Multiboot2 framebuffer deepth"
|
||||
default 32
|
||||
---help---
|
||||
Requested framebuffer deepth
|
||||
|
||||
endif # MULTBOOT2_FB
|
||||
|
||||
endif # ARCH_MULTIBOOT2
|
||||
|
||||
config ARCH_PVHBOOT
|
||||
|
|
|
@ -72,7 +72,11 @@ if(CONFIG_SMP)
|
|||
endif()
|
||||
|
||||
if(CONFIG_MULTBOOT2_FB_TERM)
|
||||
list(APPEND SRCS intel64_mbfb.c)
|
||||
list(APPEND SRCS intel64_fbterm.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_MULTBOOT2_FB)
|
||||
list(APPEND SRCS intel64_fb.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_ARCH_INTEL64_HAVE_TSC)
|
||||
|
|
|
@ -63,7 +63,11 @@ endif
|
|||
# Configuration-dependent intel64 files
|
||||
|
||||
ifeq ($(CONFIG_MULTBOOT2_FB_TERM),y)
|
||||
CHIP_CSRCS += intel64_mbfb.c
|
||||
CHIP_CSRCS += intel64_fbterm.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MULTBOOT2_FB),y)
|
||||
CHIP_CSRCS += intel64_fb.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_INTEL64_HAVE_TSC),y)
|
||||
|
|
314
arch/x86_64/src/intel64/intel64_fb.c
Normal file
314
arch/x86_64/src/intel64/intel64_fb.c
Normal file
|
@ -0,0 +1,314 @@
|
|||
/****************************************************************************
|
||||
* arch/x86_64/src/intel64/intel64_fb.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <arch/multiboot2.h>
|
||||
|
||||
#include <nuttx/video/fb.h>
|
||||
|
||||
#include "x86_64_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct multiboot_fb_s
|
||||
{
|
||||
/* Framebuffer interface */
|
||||
|
||||
struct fb_vtable_s vtable;
|
||||
|
||||
/* Framebuffer video information */
|
||||
|
||||
struct fb_videoinfo_s videoinfo;
|
||||
|
||||
/* Framebuffer plane information */
|
||||
|
||||
struct fb_planeinfo_s planeinfo;
|
||||
|
||||
/* Framebuffer base address */
|
||||
|
||||
void *baseaddr;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Framebuffer interface */
|
||||
|
||||
static int intel64_getvideoinfo(struct fb_vtable_s *vtable,
|
||||
struct fb_videoinfo_s *vinfo);
|
||||
static int intel64_getplaneinfo(struct fb_vtable_s *vtable,
|
||||
int planeno,
|
||||
struct fb_planeinfo_s *pinfo);
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static uint8_t intel64_fb_getfmt(uint8_t bpp, uint8_t type);
|
||||
static void intel64_fb_clear(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern struct multiboot_tag_framebuffer *g_mb_fb_tag;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct multiboot_fb_s g_fb =
|
||||
{
|
||||
.vtable =
|
||||
{
|
||||
.getvideoinfo = intel64_getvideoinfo,
|
||||
.getplaneinfo = intel64_getplaneinfo
|
||||
},
|
||||
|
||||
.baseaddr = NULL
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: intel64_getvideoinfo
|
||||
****************************************************************************/
|
||||
|
||||
static int intel64_getvideoinfo(struct fb_vtable_s *vtable,
|
||||
struct fb_videoinfo_s *vinfo)
|
||||
{
|
||||
struct multiboot_fb_s *priv = (struct multiboot_fb_s *)vtable;
|
||||
|
||||
memcpy(vinfo, &priv->videoinfo, sizeof(struct fb_videoinfo_s));
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: intel64_getplaneinfo
|
||||
****************************************************************************/
|
||||
|
||||
static int intel64_getplaneinfo(struct fb_vtable_s *vtable,
|
||||
int planeno,
|
||||
struct fb_planeinfo_s *pinfo)
|
||||
{
|
||||
struct multiboot_fb_s *priv = (struct multiboot_fb_s *)vtable;
|
||||
|
||||
if (planeno == 0)
|
||||
{
|
||||
memcpy(pinfo, &priv->planeinfo, sizeof(struct fb_planeinfo_s));
|
||||
return OK;
|
||||
}
|
||||
|
||||
gerr("ERROR: Returning EINVAL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: intel64_fb_getfmt
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t intel64_fb_getfmt(uint8_t bpp, uint8_t type)
|
||||
{
|
||||
if (type != MULTIBOOT_FRAMEBUFFER_TYPE_RGB)
|
||||
{
|
||||
/* Only RGB type supported */
|
||||
|
||||
gerr("ERROR: not supported type=%d\n", type);
|
||||
PANIC();
|
||||
}
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
return FB_FMT_RGB8;
|
||||
}
|
||||
|
||||
case 24:
|
||||
{
|
||||
return FB_FMT_RGB24;
|
||||
}
|
||||
|
||||
case 32:
|
||||
{
|
||||
return FB_FMT_RGB32;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
gerr("ERROR: not supported BPP=%d\n", bpp);
|
||||
PANIC();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: intel64_fb_clear
|
||||
****************************************************************************/
|
||||
|
||||
static void intel64_fb_clear(void)
|
||||
{
|
||||
if (g_fb.baseaddr == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memset(g_fb.baseaddr, 0, g_fb.planeinfo.stride * g_fb.videoinfo.yres);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the framebuffer video hardware associated with the display.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned on success; a negated errno value is returned on any
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_fbinitialize(int display)
|
||||
{
|
||||
struct multiboot_tag_framebuffer *fbt = g_mb_fb_tag;
|
||||
struct multiboot_fb_s *fb = &g_fb;
|
||||
|
||||
UNUSED(display);
|
||||
|
||||
/* Return error if multiboot tag is empty */
|
||||
|
||||
if (fbt == NULL)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Get framebuffer base address */
|
||||
|
||||
fb->baseaddr = (void *)(uintptr_t)fbt->common.framebuffer_addr;
|
||||
|
||||
/* Get video info */
|
||||
|
||||
fb->videoinfo.xres = fbt->common.framebuffer_width;
|
||||
fb->videoinfo.yres = fbt->common.framebuffer_height;
|
||||
fb->videoinfo.nplanes = 1;
|
||||
fb->videoinfo.fmt = intel64_fb_getfmt(fbt->common.framebuffer_bpp,
|
||||
fbt->common.framebuffer_type);
|
||||
|
||||
/* Get plane info */
|
||||
|
||||
fb->planeinfo.fbmem = fb->baseaddr;
|
||||
fb->planeinfo.fblen = (fbt->common.framebuffer_pitch *
|
||||
fb->videoinfo.yres);
|
||||
fb->planeinfo.stride = fbt->common.framebuffer_pitch;
|
||||
fb->planeinfo.bpp = fbt->common.framebuffer_bpp;
|
||||
|
||||
/* Map framebuffer memory.
|
||||
* NOTE: framebuffer base address may lie above 4GB for real hardware,
|
||||
* in that case CONFIG_MM_PGALLOC=y must be enabled so
|
||||
* up_map_region() can map this address.
|
||||
*/
|
||||
|
||||
up_map_region(fb->baseaddr, fb->planeinfo.stride * fb->videoinfo.yres,
|
||||
X86_PAGE_WR | X86_PAGE_PRESENT |
|
||||
X86_PAGE_NOCACHE | X86_PAGE_GLOBAL);
|
||||
|
||||
/* Clear frambufer */
|
||||
|
||||
intel64_fb_clear();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbgetvplane
|
||||
*
|
||||
* Description:
|
||||
* Return a a reference to the framebuffer object for the specified video
|
||||
* plane of the specified plane.
|
||||
* Many OSDs support multiple planes of video.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
* vplane - Identifies the plane being queried.
|
||||
*
|
||||
* Returned Value:
|
||||
* A non-NULL pointer to the frame buffer access structure is returned on
|
||||
* success; NULL is returned on any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
|
||||
{
|
||||
if (vplane == 0)
|
||||
{
|
||||
return &g_fb.vtable;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fbuninitialize
|
||||
*
|
||||
* Description:
|
||||
* Uninitialize the framebuffer support for the specified display.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - In the case of hardware with multiple displays, this
|
||||
* specifies the display. Normally this is zero.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_fbuninitialize(int display)
|
||||
{
|
||||
UNUSED(display);
|
||||
|
||||
/* Clear frambufer */
|
||||
|
||||
intel64_fb_clear();
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* arch/x86_64/src/intel64/intel64_mbfb.c
|
||||
* arch/x86_64/src/intel64/intel64_fbterm.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
|
@ -119,6 +119,16 @@ header_start:
|
|||
.long MULTIBOOT_TAG_TYPE_ACPI_OLD
|
||||
.long MULTIBOOT_TAG_TYPE_ACPI_NEW
|
||||
|
||||
#ifdef CONFIG_MULTBOOT2_FB
|
||||
.short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
|
||||
.short 0 /* flags, none set */
|
||||
.long 20 /* size, including itself (short + short + long) */
|
||||
.long CONFIG_MULTBOOT2_FB_WIDTH /* width */
|
||||
.long CONFIG_MULTBOOT2_FB_HEIGHT /* height */
|
||||
.long CONFIG_MULTBOOT2_FB_DEEPTH /* depth */
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
.short MULTIBOOT_HEADER_TAG_END
|
||||
.short 0 /* flags, none set */
|
||||
.long 8 /* size, including itself (short + short + long) */
|
||||
|
|
|
@ -46,6 +46,10 @@ uint32_t g_mb_magic __attribute__((section(".loader.bss")));
|
|||
uint32_t g_mb_info_struct __attribute__((section(".loader.bss")));
|
||||
uintptr_t g_acpi_rsdp = 0;
|
||||
|
||||
#ifdef CONFIG_MULTBOOT2_FB
|
||||
struct multiboot_tag_framebuffer *g_mb_fb_tag = NULL;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -98,11 +102,15 @@ static void x86_64_mb2_config(void)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MULTBOOT2_FB_TERM
|
||||
#ifdef CONFIG_MULTBOOT2_FB
|
||||
case MULTIBOOT_TAG_TYPE_FRAMEBUFFER:
|
||||
{
|
||||
x86_64_mb2_fbinitialize(
|
||||
(struct multiboot_tag_framebuffer *)tag);
|
||||
/* We have to postpone frame buffer initialization because
|
||||
* at this boot stage we can't map >4GB memory yet and it's
|
||||
* possible that frame bufer address is above 4GB.
|
||||
*/
|
||||
|
||||
g_mb_fb_tag = (struct multiboot_tag_framebuffer *)tag;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
# include <nuttx/pci/pci.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB
|
||||
# include <nuttx/video/fb.h>
|
||||
#endif
|
||||
|
||||
#include "qemu_intel64.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -97,5 +101,15 @@ int qemu_bringup(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIDEO_FB
|
||||
/* Initialize and register the framebuffer driver */
|
||||
|
||||
ret = fb_register(0, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: fb_register() failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue