1// Copyright 2016 The Fuchsia Authors 2// 3// Use of this source code is governed by a MIT-style 4// license that can be found in the LICENSE file or at 5// https://opensource.org/licenses/MIT 6 7#include <assert.h> 8#include <dev/udisplay.h> 9#include <lib/crashlog.h> 10#include <lib/debuglog.h> 11#include <lib/gfxconsole.h> 12#include <lib/io.h> 13#include <platform.h> 14#include <stdlib.h> 15#include <string.h> 16#include <trace.h> 17#include <vm/vm_aspace.h> 18#include <vm/vm_object.h> 19 20#define LOCAL_TRACE 0 21 22constexpr uint kFramebufferArchMmuFlags = ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE; 23 24static char crashlogbuf[4096u]; 25 26struct udisplay_info { 27 void* framebuffer_virt; 28 size_t framebuffer_size; 29 struct display_info info; 30 fbl::RefPtr<VmMapping> framebuffer_vmo_mapping; 31}; 32 33static struct udisplay_info g_udisplay = {}; 34 35zx_status_t udisplay_init(void) { 36 return ZX_OK; 37} 38 39void dlog_bluescreen_halt(void) { 40 size_t len = crashlog_to_string(crashlogbuf, sizeof(crashlogbuf)); 41 platform_stow_crashlog(crashlogbuf, len); 42 if (g_udisplay.framebuffer_virt == 0) 43 return; 44} 45 46void udisplay_clear_framebuffer_vmo() { 47 if (g_udisplay.framebuffer_vmo_mapping) { 48 g_udisplay.framebuffer_size = 0; 49 g_udisplay.framebuffer_virt = 0; 50 g_udisplay.framebuffer_vmo_mapping->Destroy(); 51 g_udisplay.framebuffer_vmo_mapping = nullptr; 52 } 53} 54 55zx_status_t udisplay_set_framebuffer(fbl::RefPtr<VmObject> vmo) { 56 udisplay_clear_framebuffer_vmo(); 57 58 const size_t size = vmo->size(); 59 fbl::RefPtr<VmMapping> mapping; 60 zx_status_t status = VmAspace::kernel_aspace()->RootVmar()->CreateVmMapping( 61 0 /* ignored */, size, 0 /* align pow2 */, 0 /* vmar flags */, 62 fbl::move(vmo), 0, kFramebufferArchMmuFlags, "framebuffer_vmo", &mapping); 63 if (status != ZX_OK) 64 return status; 65 66 status = mapping->MapRange(0, size, true); 67 if (status != ZX_OK) { 68 mapping->Destroy(); 69 return status; 70 } 71 72 g_udisplay.framebuffer_virt = reinterpret_cast<void*>(mapping->base()); 73 g_udisplay.framebuffer_size = size; 74 g_udisplay.framebuffer_vmo_mapping = mapping; 75 return ZX_OK; 76} 77 78zx_status_t udisplay_set_display_info(struct display_info* display) { 79 memcpy(&g_udisplay.info, display, sizeof(struct display_info)); 80 return ZX_OK; 81} 82 83zx_status_t udisplay_bind_gfxconsole(void) { 84 if (g_udisplay.framebuffer_virt == 0) 85 return ZX_ERR_NOT_FOUND; 86 87 // bind the display to the gfxconsole 88 g_udisplay.info.framebuffer = g_udisplay.framebuffer_virt; 89 g_udisplay.info.flags = DISPLAY_FLAG_NEEDS_CACHE_FLUSH | DISPLAY_FLAG_CRASH_FRAMEBUFFER; 90 gfxconsole_bind_display(&g_udisplay.info, nullptr); 91 92 return ZX_OK; 93} 94