From: YANG Qiao <yangqiao0...@me.com> --- c/src/lib/libbsp/arm/raspberrypi/Makefile.am | 6 +- c/src/lib/libbsp/arm/raspberrypi/console/fb.c | 331 +++++++++++++++++++++ c/src/lib/libbsp/arm/raspberrypi/include/bsp.h | 2 + .../arm/raspberrypi/startup/bspgetworkarea.c | 61 ++++ c/src/lib/libbsp/arm/raspberrypi/startup/linkcmds | 5 +- c/src/lib/libbsp/arm/raspberrypi/startup/mminit.c | 42 +++ 6 files changed, 443 insertions(+), 4 deletions(-) create mode 100644 c/src/lib/libbsp/arm/raspberrypi/console/fb.c create mode 100644 c/src/lib/libbsp/arm/raspberrypi/startup/bspgetworkarea.c create mode 100644 c/src/lib/libbsp/arm/raspberrypi/startup/mminit.c
diff --git a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am index 81eeb9a..41817b1 100644 --- a/c/src/lib/libbsp/arm/raspberrypi/Makefile.am +++ b/c/src/lib/libbsp/arm/raspberrypi/Makefile.am @@ -78,7 +78,6 @@ libbsp_a_LIBADD = # Shared libbsp_a_SOURCES += ../../shared/bootcard.c libbsp_a_SOURCES += ../../shared/bspclean.c -libbsp_a_SOURCES += ../../shared/bspgetworkarea.c libbsp_a_SOURCES += ../../shared/bsplibc.c libbsp_a_SOURCES += ../../shared/bsppost.c libbsp_a_SOURCES += ../../shared/bsppredriverhook.c @@ -94,6 +93,8 @@ libbsp_a_SOURCES += ../shared/arm-cp15-set-ttb-entries.c # Startup libbsp_a_SOURCES += ../../shared/bspreset_loop.c libbsp_a_SOURCES += startup/bspstart.c +libbsp_a_SOURCES += startup/cmdline.c +libbsp_a_SOURCES += startup/bspgetworkarea.c # IRQ libbsp_a_SOURCES += ../shared/arm-cp15-set-exception-handler.c @@ -112,6 +113,7 @@ libbsp_a_SOURCES += ../../shared/console_select.c libbsp_a_SOURCES += ../../shared/console_write.c libbsp_a_SOURCES += console/console-config.c libbsp_a_SOURCES += console/usart.c +libbsp_a_SOURCES += console/fb.c # clock libbsp_a_SOURCES += clock/clockdrv.c ../../../shared/clockdrv_shell.h @@ -141,7 +143,7 @@ libbsp_a_SOURCES += startup/bspstarthooks.c # LIBMM libbsp_a_SOURCES += startup/mm_config_table.c -libbsp_a_SOURCES += ../shared/mminit.c +libbsp_a_SOURCES += startup/mminit.c ############################################################################### # Network # diff --git a/c/src/lib/libbsp/arm/raspberrypi/console/fb.c b/c/src/lib/libbsp/arm/raspberrypi/console/fb.c new file mode 100644 index 0000000..a83d560 --- /dev/null +++ b/c/src/lib/libbsp/arm/raspberrypi/console/fb.c @@ -0,0 +1,331 @@ +/** + * @file + * + * @ingroup raspberrypi + * + * @brief framebuffer support. + */ + +/* + * Copyright (c) 2015 Yang Qiao + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * + * http://www.rtems.org/license/LICENSE + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> + +#include <bsp.h> +#include <bsp/raspberrypi.h> +#include <bsp/mailbox.h> +#include <bsp/vc.h> + +#include <rtems.h> +#include <rtems/libio.h> +#include <rtems/fb.h> +#include <rtems/framebuffer.h> +#include <rtems/score/atomic.h> + +#define SCREEN_WIDTH 1024 +#define SCREEN_HEIGHT 768 +#define BPP 32 +#define BUFFER_SIZE (SCREEN_WIDTH*SCREEN_HEIGHT*BPP/8) + +/* flag to limit driver to protect against multiple opens */ +static Atomic_Flag driver_mutex; + +/* + * screen information for the driver (fb0). + */ + +static struct fb_var_screeninfo fb_var_info = { + .xres = SCREEN_WIDTH, + .yres = SCREEN_HEIGHT, + .bits_per_pixel = BPP +}; + +static struct fb_fix_screeninfo fb_fix_info = { + .smem_start = (void *) NULL, + .smem_len = 0, + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .line_length = 0 +}; + +int raspberrypi_get_fix_screen_info( struct fb_fix_screeninfo *info ) +{ + *info = fb_fix_info; + return 0; +} + +int raspberrypi_get_var_screen_info( struct fb_var_screeninfo *info ) +{ + *info = fb_var_info; + return 0; +} + +static int +find_mode_from_cmdline(void) +{ + const char* opt; + char* endptr; + uint32_t width; + uint32_t height; + uint32_t bpp; + opt = rpi_cmdline_arg("--video="); + if (opt) + { + opt += sizeof("--video=")-1; + width = strtol(opt, &endptr, 10); + if (*endptr != 'x') + { + return -2; + } + opt = endptr+1; + height = strtol(opt, &endptr, 10); + switch (*endptr) + { + case '-': + opt = endptr+1; + if (strlen(opt) <= 2) + bpp = strtol(opt, &endptr, 10); + else + { + bpp = strtol(opt, &endptr, 10); + if (*endptr != ' ') + { + return -4; + } + } + case ' ': + case 0: + break; + default: + return -3; + } + } + else + return -1; + + fb_var_info.xres = width; + fb_var_info.yres = height; + + return 0; +} + +static int +find_mode_from_vc(void) +{ + bcm2835_get_display_size_entries entries; + bcm2835_mailbox_get_display_size(&entries); + unsigned int width = entries.width; + unsigned int height = entries.height; + + if (width == 0 || height == 0) + { + fb_var_info.xres = SCREEN_WIDTH; + fb_var_info.yres = SCREEN_HEIGHT; + } + else + { + fb_var_info.xres = width; + fb_var_info.yres = height; + } + + return 0; +} + +static bool +hdmi_is_present(void) +{ + bcm2835_get_display_size_entries entries; + bcm2835_mailbox_get_display_size(&entries); + if(entries.width == 0x290 && entries.height ==0x1A0 ) + { + return false; + } + else + { + return true; + } +} + +int +fb_init(void) +{ + if (fb_fix_info.smem_start != NULL) + { + return -2; + } + + if (hdmi_is_present() == false) + { + return -3; + } + + if (find_mode_from_cmdline()) + { + if(find_mode_from_vc()) + return -1; + } + + bcm2835_init_frame_buffer_entries init_frame_buffer_entries; + init_frame_buffer_entries.xres = fb_var_info.xres; + init_frame_buffer_entries.yres = fb_var_info.yres; + init_frame_buffer_entries.xvirt = fb_var_info.xres; + init_frame_buffer_entries.yvirt = fb_var_info.yres; + init_frame_buffer_entries.depth = fb_var_info.bits_per_pixel; + init_frame_buffer_entries.pixel_order = bcm2835_mailbox_pixel_order_rgb; + init_frame_buffer_entries.alpha_mode = bcm2835_mailbox_alpha_mode_0_opaque; + init_frame_buffer_entries.voffset_x = 0; + init_frame_buffer_entries.voffset_y = 0; + init_frame_buffer_entries.overscan_left = 0; + init_frame_buffer_entries.overscan_right = 0; + init_frame_buffer_entries.overscan_top = 0; + init_frame_buffer_entries.overscan_bottom = 0; + bcm2835_mailbox_init_frame_buffer(&init_frame_buffer_entries); + + bcm2835_get_pitch_entries get_pitch_entries; + bcm2835_mailbox_get_pitch(&get_pitch_entries); + + fb_var_info.xres = init_frame_buffer_entries.xres; + fb_var_info.yres = init_frame_buffer_entries.yres; + fb_var_info.bits_per_pixel = init_frame_buffer_entries.depth; + fb_fix_info.smem_start = init_frame_buffer_entries.base; + fb_fix_info.smem_len = init_frame_buffer_entries.size; + fb_fix_info.line_length = get_pitch_entries.pitch; + + return 0; +} + + +/* + * fbds device driver initialize entry point. + */ + +rtems_device_driver +frame_buffer_initialize (rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + rtems_status_code status; + + /* register the devices */ + status = rtems_io_register_name (FRAMEBUFFER_DEVICE_0_NAME, major, 0); + if (status != RTEMS_SUCCESSFUL) { + printk ("[!] error registering framebuffer\n"); + rtems_fatal_error_occurred (status); + } + _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); + return RTEMS_SUCCESSFUL; +} + +/* + * fbds device driver open operation. + */ + +rtems_device_driver +frame_buffer_open (rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + if (_Atomic_Flag_test_and_set(&driver_mutex, ATOMIC_ORDER_ACQUIRE) != 0 ) { + printk( "FB_CIRRUS could not lock driver_mutex\n" ); + return RTEMS_UNSATISFIED; + } + + memset ((void *)fb_fix_info.smem_start, 0, fb_fix_info.smem_len); + return RTEMS_SUCCESSFUL; +} + +/* + * fbds device driver close operation. + */ + +rtems_device_driver +frame_buffer_close (rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + /* restore previous state. for VGA this means return to text mode. + * leave out if graphics hardware has been initialized in + * frame_buffer_initialize() */ + _Atomic_Flag_clear(&driver_mutex, ATOMIC_ORDER_RELEASE); + memset ((void *)fb_fix_info.smem_start, 0, fb_fix_info.smem_len); + return RTEMS_SUCCESSFUL; +} + +/* + * fbds device driver read operation. + */ + +rtems_device_driver +frame_buffer_read (rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + rw_args->bytes_moved = + ((rw_args->offset + rw_args->count) > fb_fix_info.smem_len ) ? + (fb_fix_info.smem_len - rw_args->offset) :rw_args->count; + memcpy( rw_args->buffer, + (const void *) (fb_fix_info.smem_start + rw_args->offset), + rw_args->bytes_moved); + return RTEMS_SUCCESSFUL; +} + +/* + * fbds device driver write operation. + */ + +rtems_device_driver +frame_buffer_write (rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + rtems_libio_rw_args_t *rw_args = (rtems_libio_rw_args_t *)arg; + rw_args->bytes_moved = + ((rw_args->offset + rw_args->count) > fb_fix_info.smem_len ) ? + (fb_fix_info.smem_len - rw_args->offset) : rw_args->count; + memcpy( (void *) (fb_fix_info.smem_start + rw_args->offset), + rw_args->buffer, + rw_args->bytes_moved); + return RTEMS_SUCCESSFUL; +} + +/* + * ioctl entry point. + */ + +rtems_device_driver +frame_buffer_control (rtems_device_major_number major, + rtems_device_minor_number minor, void *arg) +{ + rtems_libio_ioctl_args_t *args = arg; + + /* XXX check minor */ + + switch (args->command) { + case FBIOGET_VSCREENINFO: + memcpy (args->buffer, &fb_var_info, sizeof (fb_var_info)); + args->ioctl_return = 0; + break; + case FBIOGET_FSCREENINFO: + memcpy (args->buffer, &fb_fix_info, sizeof (fb_fix_info)); + args->ioctl_return = 0; + break; + case FBIOGETCMAP: + args->ioctl_return = 0; + break; + case FBIOPUTCMAP: + args->ioctl_return = 0; + break; + + default: + args->ioctl_return = 0; + break; + + } + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libbsp/arm/raspberrypi/include/bsp.h b/c/src/lib/libbsp/arm/raspberrypi/include/bsp.h index 4029d52..a3a0f71 100644 --- a/c/src/lib/libbsp/arm/raspberrypi/include/bsp.h +++ b/c/src/lib/libbsp/arm/raspberrypi/include/bsp.h @@ -33,6 +33,8 @@ extern "C" { #endif /* __cplusplus */ +#define RPI_L2_CACHE_ENABLE 1 + #define BSP_FEATURE_IRQ_EXTENSION void rpi_init_cmdline(void); diff --git a/c/src/lib/libbsp/arm/raspberrypi/startup/bspgetworkarea.c b/c/src/lib/libbsp/arm/raspberrypi/startup/bspgetworkarea.c new file mode 100644 index 0000000..07a38e9 --- /dev/null +++ b/c/src/lib/libbsp/arm/raspberrypi/startup/bspgetworkarea.c @@ -0,0 +1,61 @@ +/** + * @file + * + * @ingroup arm_start + * + * @brief Raspberry pi workarea initialization. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * Copyright (c) 2011-2012 embedded brains GmbH. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + * + * Copyright (c) 2015 YANG Qiao + */ + +#include <bsp.h> +#include <bsp/bootcard.h> +#include <bsp/vc.h> +#ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN + #include <rtems/config.h> +#endif + +#if defined(HAS_UBOOT) && !defined(BSP_DISABLE_UBOOT_WORK_AREA_CONFIG) + #define USE_UBOOT +#endif + +extern char WorkAreaBase[]; + +#ifdef USE_UBOOT + #include <bsp/u-boot.h> +#else + extern char RamBase[]; + extern char RamSize[]; +#endif + +void bsp_work_area_initialize(void) +{ + uintptr_t work_base = (uintptr_t) WorkAreaBase; + uintptr_t ram_end; + bcm2835_get_arm_memory_entries arm_entry; + bcm2835_get_vc_memory_entries vc_entry; + + #ifdef USE_UBOOT + ram_end = (uintptr_t) bsp_uboot_board_info.bi_memstart + + bsp_uboot_board_info.bi_memsize; + #else + ram_end = (uintptr_t)RamBase + (uintptr_t)RamSize; + #endif + + #ifdef BSP_INTERRUPT_STACK_AT_WORK_AREA_BEGIN + work_base += rtems_configuration_get_interrupt_stack_size(); + #endif + + bcm2835_mailbox_get_vc_memory(&vc_entry); + ram_end = ram_end>vc_entry.base? vc_entry.base: ram_end; + bsp_work_area_initialize_default( (void *) work_base, ram_end - work_base ); +} diff --git a/c/src/lib/libbsp/arm/raspberrypi/startup/linkcmds b/c/src/lib/libbsp/arm/raspberrypi/startup/linkcmds index f1ad11c..8972230 100644 --- a/c/src/lib/libbsp/arm/raspberrypi/startup/linkcmds +++ b/c/src/lib/libbsp/arm/raspberrypi/startup/linkcmds @@ -37,8 +37,9 @@ MEMORY { VECTOR_RAM (AIW) : ORIGIN = 0x0 , LENGTH = 0x8000 - RAM (AIW) : ORIGIN = 0x00008000, LENGTH = 128M - 48K - RAM_MMU (AIW) : ORIGIN = 128M - 16k, LENGTH = 16k + GPU_RAM (AIW) : ORIGIN = 512M - 64M, LENGTH = 64M + RAM (AIW) : ORIGIN = 0x00008000, LENGTH = 512M - 64M - 48K + RAM_MMU (AIW) : ORIGIN = 512M - 64M - 16k, LENGTH = 16k } REGION_ALIAS ("REGION_START", RAM); diff --git a/c/src/lib/libbsp/arm/raspberrypi/startup/mminit.c b/c/src/lib/libbsp/arm/raspberrypi/startup/mminit.c new file mode 100644 index 0000000..e012060 --- /dev/null +++ b/c/src/lib/libbsp/arm/raspberrypi/startup/mminit.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015 Yang Qiao + * based on work by: + * Copyright (c) 2013 Hesham AL-Matary. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#define ARM_CP15_TEXT_SECTION BSP_START_TEXT_SECTION + +#include <bsp/start.h> +#include <bsp/arm-cp15-start.h> +#include <bsp/linker-symbols.h> +#include <bsp/mm.h> +#include <rtems/fb.h> + +extern int raspberrypi_get_var_screen_info( struct fb_var_screeninfo *info ); + +BSP_START_TEXT_SECTION void bsp_memory_management_initialize(void) +{ + uint32_t ctrl = arm_cp15_get_control(); + + ctrl |= ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_S | ARM_CP15_CTRL_XP; + + struct fb_fix_screeninfo fb_fix_info; + raspberrypi_get_fix_screen_info(&fb_fix_info); + + arm_cp15_start_setup_translation_table_and_enable_mmu_and_cache( + ctrl, + (uint32_t *) bsp_translation_table_base, + ARM_MMU_DEFAULT_CLIENT_DOMAIN, + &arm_cp15_start_mmu_config_table[0], + arm_cp15_start_mmu_config_table_size + ); + + arm_cp15_set_translation_table_entries(fb_fix_info.smem_start, + fb_fix_info.smem_start + + fb_fix_info.smem_len, + ARMV7_MMU_DATA_READ_WRITE_CACHED); +} -- 2.1.0 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel