Ticket #6105: 0004-OpenFirmware-Add-frame-buffer-support.patch

File 0004-OpenFirmware-Add-frame-buffer-support.patch, 7.2 KB (added by andreasf, 10 years ago)

draft patch: implement frame buffer support

  • headers/private/kernel/boot/platform/openfirmware/platform_arch.h

    From 6e7f69f5c9166f1f2ee926083a64663155a52f18 Mon Sep 17 00:00:00 2001
    From: Andreas Faerber <andreas.faerber@web.de>
    Date: Tue, 1 Jun 2010 19:15:59 +0200
    Subject: [PATCH 4/4] OpenFirmware: Add frame buffer support
    
    ---
     .../boot/platform/openfirmware/platform_arch.h     |    4 +
     src/system/boot/platform/openfirmware/Jamfile      |   12 ++-
     .../boot/platform/openfirmware/arch/ppc/mmu.cpp    |   19 ++++
     src/system/boot/platform/openfirmware/video.cpp    |  100 +++++++++++++++++++-
     4 files changed, 130 insertions(+), 5 deletions(-)
    
    diff --git a/headers/private/kernel/boot/platform/openfirmware/platform_arch.h b/headers/private/kernel/boot/platform/openfirmware/platform_arch.h
    index 7d21e2a..c420aa7 100644
    a b extern "C" {  
    1616
    1717/* memory management */
    1818   
     19// For use with arch_mmu_map_physical_memory()
     20static const uint32 kDefaultPageMode = 0x3; // present, R/W
     21
    1922extern status_t arch_set_callback(void);
    2023extern void *arch_mmu_allocate(void *address, size_t size, uint8 protection,
    2124    bool exactAddress);
    2225extern status_t arch_mmu_free(void *address, size_t size);
    2326extern status_t arch_mmu_init(void);
     27extern addr_t arch_mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 mode);
    2428
    2529/* CPU */
    2630
  • src/system/boot/platform/openfirmware/Jamfile

    diff --git a/src/system/boot/platform/openfirmware/Jamfile b/src/system/boot/platform/openfirmware/Jamfile
    index 00c2b6d..bf3785c 100644
    a b SubDir HAIKU_TOP src system boot platform openfirmware ;  
    22
    33SubDirC++Flags -D_BOOT_MODE -fno-rtti ;
    44
     5local genericPlatformSources =
     6    text_menu.cpp
     7    video_blit.cpp
     8    video_splash.cpp
     9    video_rle.cpp
     10;
     11
    512KernelMergeObject boot_platform_openfirmware.o :
    613    console.cpp
    714    debug.c
    KernelMergeObject boot_platform_openfirmware.o :  
    1926    openfirmware.cpp
    2027    openfirmware_devices.cpp
    2128
    22     # generic
    23     text_menu.cpp
     29    $(genericPlatformSources)
    2430    :
    2531    : boot_platform_openfirmware_$(TARGET_ARCH).a
    2632;
    2733
    28 SEARCH on [ FGristFiles text_menu.cpp ]
     34SEARCH on [ FGristFiles $(genericPlatformSources) ]
    2935    = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ;
    3036SEARCH on [ FGristFiles openfirmware.cpp openfirmware_devices.cpp ]
    3137    = [ FDirName $(HAIKU_TOP) src system kernel platform openfirmware ] ;
  • src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp

    diff --git a/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp b/src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp
    index a5429ef..4aaa7f8 100644
    a b find_free_virtual_range(void *base, size_t size)  
    413413}
    414414
    415415
     416// TODO: This is a hack identity-mapping the physical memory
     417// since we don't seem to have the concept of next virtual addresses/pages in ppc (yet?)
     418extern "C" addr_t
     419arch_mmu_map_physical_memory(addr_t physicalAddress, size_t size, uint32 mode)
     420{
     421    addr_t address = physicalAddress/*sNextVirtualAddress*/;
     422    addr_t pageOffset = physicalAddress & (B_PAGE_SIZE - 1);
     423
     424    physicalAddress -= pageOffset;
     425    size += pageOffset;
     426
     427    for (addr_t offset = 0; offset < size; offset += B_PAGE_SIZE) {
     428        map_page((void*)(physicalAddress + offset)/*get_next_virtual_page()*/, (void*)(physicalAddress + offset), mode);
     429    }
     430
     431    return address /*+ pageOffset*/;
     432}
     433
     434
    416435extern "C" void *
    417436arch_mmu_allocate(void *_virtualAddress, size_t size, uint8 _protection,
    418437    bool exactAddress)
  • src/system/boot/platform/openfirmware/video.cpp

    diff --git a/src/system/boot/platform/openfirmware/video.cpp b/src/system/boot/platform/openfirmware/video.cpp
    index a2ff181..d7f9c27 100644
    a b  
    11/*
    22 * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
     3 * Copyright 2010, Andreas Färber <andreas.faerber@web.de>
    34 * Distributed under the terms of the MIT License.
    45 */
    56
    67
     8#include <platform_arch.h>
    79#include <boot/stage2.h>
    810#include <boot/platform.h>
     11#include <boot/platform/generic/video.h>
     12#include <platform/openfirmware/openfirmware.h>
     13#include <arch_mmu.h>
     14
     15
     16static int sScreen;
     17static addr_t sFrameBuffer;
     18
     19
     20void
     21platform_blit4(addr_t frameBuffer, const uint8 *data,
     22    uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top)
     23{
     24    if (!data)
     25        return;
     26    // TODO
     27}
     28
     29
     30extern "C" void
     31platform_set_palette(const uint8 *palette)
     32{
     33    switch (gKernelArgs.frame_buffer.depth) {
     34        case 8:
     35            // TODO try to optimize with set-colors
     36            for (int index = 0; index < 256; index++) {
     37                of_call_method(sScreen, "color!", 4, 0, index,
     38                    palette[index * 3 + 2],
     39                    palette[index * 3 + 1],
     40                    palette[index * 3 + 0]);
     41            }
     42            break;
     43        default:
     44            break;
     45    }
     46}
    947
    1048
    1149extern "C" void
    platform_switch_to_logo(void)  
    1553    if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) != 0)
    1654        return;
    1755
    18     // ToDo: implement me
     56    if (sScreen == OF_FAILED)
     57        return;
     58    int package = of_instance_to_package(sScreen);
     59    if (package == OF_FAILED)
     60        return;
     61    int width, height;
     62    if (of_call_method(sScreen, "dimensions", 0, 2, &height, &width)
     63            == OF_FAILED) {
     64        if (of_getprop(package, "width", &width, sizeof(int)) == OF_FAILED)
     65            return;
     66        if (of_getprop(package, "height", &height, sizeof(int)) == OF_FAILED)
     67            return;
     68    }
     69    int depth;
     70    if (of_getprop(package, "depth", &depth, sizeof(int)) == OF_FAILED)
     71        return;
     72    int lineBytes;
     73    if (of_getprop(package, "linebytes", &lineBytes, sizeof(int))
     74            == OF_FAILED)
     75        return;
     76    if (of_getprop(package, "address",
     77            &gKernelArgs.frame_buffer.physical_buffer.start, sizeof(int))
     78            == OF_FAILED)
     79        return;
     80    gKernelArgs.frame_buffer.width = width;
     81    gKernelArgs.frame_buffer.height = height;
     82    gKernelArgs.frame_buffer.depth = depth;
     83    gKernelArgs.frame_buffer.bytes_per_row = lineBytes;
     84
     85    addr_t lastBase = gKernelArgs.frame_buffer.physical_buffer.start;
     86    size_t lastSize = gKernelArgs.frame_buffer.physical_buffer.size;
     87
     88    gKernelArgs.frame_buffer.physical_buffer.size = lineBytes * height;
     89
     90    dprintf("video mode: %ux%ux%u\n", gKernelArgs.frame_buffer.width,
     91        gKernelArgs.frame_buffer.height, gKernelArgs.frame_buffer.depth);
     92
     93    gKernelArgs.frame_buffer.enabled = true;
     94
     95    // If the new frame buffer is either larger than the old one or located at
     96    // a different address, we need to remap it, so we first have to throw
     97    // away its previous mapping
     98    if (lastBase != 0
     99        && (lastBase != gKernelArgs.frame_buffer.physical_buffer.start
     100            || lastSize < gKernelArgs.frame_buffer.physical_buffer.size)) {
     101        arch_mmu_free((void *)sFrameBuffer, lastSize); // XXX not implemented
     102        lastBase = 0;
     103    }
     104    if (lastBase == 0) {
     105        // the graphics memory has not been mapped yet!
     106        sFrameBuffer = arch_mmu_map_physical_memory(
     107            gKernelArgs.frame_buffer.physical_buffer.start,
     108            gKernelArgs.frame_buffer.physical_buffer.size, kDefaultPageMode);
     109    }
     110
     111    video_display_splash(sFrameBuffer);
    19112}
    20113
    21114
    platform_init_video(void)  
    34127{
    35128    gKernelArgs.frame_buffer.enabled = 0;
    36129
    37     // ToDo: implement me
     130    sScreen = of_open("screen");
     131    if (sScreen == OF_FAILED)
     132        return B_NO_INIT;
     133
    38134    return B_OK;
    39135}
    40136