diff options
Diffstat (limited to 'bsps/shared')
91 files changed, 6530 insertions, 369 deletions
diff --git a/bsps/shared/cache/cacheimpl.h b/bsps/shared/cache/cacheimpl.h index 7e56d97f85..ddd125aa87 100644 --- a/bsps/shared/cache/cacheimpl.h +++ b/bsps/shared/cache/cacheimpl.h @@ -10,7 +10,7 @@ /* * Cache Manager * - * Copyright (C) 2014, 2018 embedded brains GmbH + * Copyright (C) 2014, 2018 embedded brains GmbH & Co. KG * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). @@ -318,6 +318,7 @@ static void smp_cache_inst_inv(void *arg) static void smp_cache_inst_inv_all(void *arg) { + (void) arg; _CPU_cache_invalidate_entire_instruction(); } diff --git a/bsps/shared/dev/btimer/btimer-cpucounter.c b/bsps/shared/dev/btimer/btimer-cpucounter.c index 3698778913..8757cb844b 100644 --- a/bsps/shared/dev/btimer/btimer-cpucounter.c +++ b/bsps/shared/dev/btimer/btimer-cpucounter.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * Copyright (c) 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/clock/arm-generic-timer.c b/bsps/shared/dev/clock/arm-generic-timer.c index 07a31fb3b7..ba159f6833 100644 --- a/bsps/shared/dev/clock/arm-generic-timer.c +++ b/bsps/shared/dev/clock/arm-generic-timer.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * Copyright (c) 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -54,15 +54,12 @@ typedef struct { static arm_gt_clock_context arm_gt_clock_instance; -/* This is defined in dev/clock/clockimpl.h */ -void Clock_isr(rtems_irq_hdl_param arg); - -static void arm_gt_clock_at_tick(void) +static void arm_gt_clock_at_tick(arm_gt_clock_context *ctx) { uint64_t cval; uint32_t interval; - interval = arm_gt_clock_instance.interval; + interval = ctx->interval; cval = arm_gt_clock_get_compare_value(); cval += interval; arm_gt_clock_set_compare_value(cval); @@ -71,7 +68,7 @@ static void arm_gt_clock_at_tick(void) #endif /* ARM_GENERIC_TIMER_UNMASK_AT_TICK */ } -static void arm_gt_clock_handler_install(void) +static void arm_gt_clock_handler_install(rtems_interrupt_handler handler) { rtems_status_code sc; @@ -79,8 +76,8 @@ static void arm_gt_clock_handler_install(void) arm_gt_clock_instance.irq, "Clock", RTEMS_INTERRUPT_UNIQUE, - (rtems_interrupt_handler) Clock_isr, - NULL + handler, + &arm_gt_clock_instance ); if (sc != RTEMS_SUCCESSFUL) { bsp_fatal(BSP_ARM_FATAL_GENERIC_TIMER_CLOCK_IRQ_INSTALL); @@ -185,14 +182,14 @@ RTEMS_SYSINIT_ITEM( RTEMS_SYSINIT_ORDER_FIRST ); -#define Clock_driver_support_at_tick() \ - arm_gt_clock_at_tick() +#define Clock_driver_support_at_tick(arg) \ + arm_gt_clock_at_tick(arg) #define Clock_driver_support_initialize_hardware() \ arm_gt_clock_initialize() #define Clock_driver_support_install_isr(isr) \ - arm_gt_clock_handler_install() + arm_gt_clock_handler_install(isr) /* Include shared source clock driver code */ #include "../../shared/dev/clock/clockimpl.h" diff --git a/bsps/shared/dev/clock/bcm2835-system-timer.c b/bsps/shared/dev/clock/bcm2835-system-timer.c new file mode 100644 index 0000000000..bb8490d03a --- /dev/null +++ b/bsps/shared/dev/clock/bcm2835-system-timer.c @@ -0,0 +1,94 @@ +/** + * @file + * + * @ingroup RTEMSDriverClockImpl + * + * @brief This source file contains the implementation of the BCM2835 Clock + * Driver. + */ + +/* + * Copyright (c) 2013 Alan Cudmore + * Copyright (c) 2016 Pavel Pisa + * + * 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 <rtems.h> +#include <bsp.h> +#include <bsp/irq.h> +#include <bsp/irq-generic.h> +#include <bsp/raspberrypi.h> +#include <rtems/timecounter.h> + +static struct timecounter raspberrypi_tc; + +static uint32_t raspberrypi_clock_get_timecount(struct timecounter *tc) +{ + return BCM2835_REG(BCM2835_GPU_TIMER_CLO); +} + +static void raspberrypi_clock_at_tick(void) +{ + uint32_t act_val; + uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_C3); + next_cmp += rtems_configuration_get_microseconds_per_tick(); + BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp; + act_val = BCM2835_REG(BCM2835_GPU_TIMER_CLO); + + /* + * Clear interrupt only if there is time left to the next tick. + * If time of the next tick has already passed then interrupt + * request stays active and fires immediately after current tick + * processing is finished. + */ + if ((int32_t)(next_cmp - act_val) > 0) + BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3; +} + +static void raspberrypi_clock_handler_install_isr( + rtems_interrupt_handler clock_isr +) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + + sc = rtems_interrupt_handler_install( + BCM2835_IRQ_ID_GPU_TIMER_M3, + "Clock", + RTEMS_INTERRUPT_UNIQUE, + clock_isr, + NULL + ); + if ( sc != RTEMS_SUCCESSFUL ) { + rtems_fatal_error_occurred(0xdeadbeef); + } +} + +static void raspberrypi_clock_initialize_hardware(void) +{ + uint32_t next_cmp = BCM2835_REG(BCM2835_GPU_TIMER_CLO); + next_cmp += rtems_configuration_get_microseconds_per_tick(); + BCM2835_REG(BCM2835_GPU_TIMER_C3) = next_cmp; + BCM2835_REG(BCM2835_GPU_TIMER_CS) = BCM2835_GPU_TIMER_CS_M3; + + raspberrypi_tc.tc_get_timecount = raspberrypi_clock_get_timecount; + raspberrypi_tc.tc_counter_mask = 0xffffffff; + raspberrypi_tc.tc_frequency = 1000000; /* 1 MHz */ + raspberrypi_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&raspberrypi_tc); +} + +#define Clock_driver_support_at_tick(arg) raspberrypi_clock_at_tick() + +#define Clock_driver_support_initialize_hardware() raspberrypi_clock_initialize_hardware() + +#define Clock_driver_support_install_isr(clock_isr) \ + raspberrypi_clock_handler_install_isr(clock_isr) + +#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR 1 + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/shared/dev/clock/clockimpl.h b/bsps/shared/dev/clock/clockimpl.h index e922c0b320..b27f7c15bc 100644 --- a/bsps/shared/dev/clock/clockimpl.h +++ b/bsps/shared/dev/clock/clockimpl.h @@ -42,6 +42,7 @@ #include <bsp.h> #include <rtems/clockdrv.h> #include <rtems/score/percpu.h> +#include <rtems/score/processormaskimpl.h> #include <rtems/score/smpimpl.h> #include <rtems/score/timecounter.h> #include <rtems/score/thread.h> @@ -63,6 +64,13 @@ #error "Fast Idle PLUS n ISRs per tick is not supported" #endif +#if defined(BSP_FEATURE_IRQ_EXTENSION) || \ + (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE) +typedef void * Clock_isr_argument; +#else +typedef rtems_vector_number Clock_isr_argument; +#endif + /** * @brief Do nothing by default. */ @@ -81,7 +89,7 @@ * @brief Do nothing by default. */ #ifndef Clock_driver_support_at_tick - #define Clock_driver_support_at_tick() + #define Clock_driver_support_at_tick( arg ) do { (void) arg; } while (0) #endif /** @@ -96,8 +104,9 @@ * instead of the default. */ #ifndef Clock_driver_timecounter_tick -static void Clock_driver_timecounter_tick( void ) +static void Clock_driver_timecounter_tick( Clock_isr_argument arg ) { + (void) arg; #if defined(CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER) rtems_clock_tick(); #elif defined(RTEMS_SMP) && defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR) @@ -139,25 +148,31 @@ volatile uint32_t Clock_driver_ticks; #error "Clock_driver_support_shutdown_hardware() is no longer supported" #endif +#if CLOCK_DRIVER_USE_FAST_IDLE +static bool _Clock_Has_watchdogs(const Per_CPU_Control *cpu) +{ + size_t i; + + for (i = 0; i < RTEMS_ARRAY_SIZE(cpu->Watchdog.Header); ++i) { + if (_Watchdog_Header_first(&cpu->Watchdog.Header[i]) != NULL) { + return true; + } + } + + return false; +} +#endif + /** * @brief Clock_isr * * This is the clock tick interrupt handler. * - * @param vector Vector number. + * @param arg is the clock interrupt handler argument. */ -#if defined(BSP_FEATURE_IRQ_EXTENSION) || \ - (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE) -void Clock_isr(void *arg); -void Clock_isr(void *arg) -{ -#else -rtems_isr Clock_isr(rtems_vector_number vector); -rtems_isr Clock_isr( - rtems_vector_number vector -) +void Clock_isr( Clock_isr_argument arg ); +void Clock_isr( Clock_isr_argument arg ) { -#endif /* * Accurate count of ISRs */ @@ -165,7 +180,7 @@ rtems_isr Clock_isr( #if CLOCK_DRIVER_USE_FAST_IDLE { - Clock_driver_timecounter_tick(); + Clock_driver_timecounter_tick( arg ); if (_SMP_Get_processor_maximum() == 1) { struct timecounter *tc; @@ -182,6 +197,7 @@ rtems_isr Clock_isr( cpu_self->thread_dispatch_disable_level == cpu_self->isr_nest_level && cpu_self->heir == cpu_self->executing && cpu_self->executing->is_idle + && _Clock_Has_watchdogs(cpu_self) ) { ISR_lock_Context lock_context; @@ -194,7 +210,7 @@ rtems_isr Clock_isr( } } - Clock_driver_support_at_tick(); + Clock_driver_support_at_tick( arg ); } #else /* @@ -202,14 +218,14 @@ rtems_isr Clock_isr( * * The counter/timer may or may not be set to automatically reload. */ - Clock_driver_support_at_tick(); + Clock_driver_support_at_tick( arg ); #if CLOCK_DRIVER_ISRS_PER_TICK /* * The driver is multiple ISRs per clock tick. */ if ( !Clock_driver_isrs ) { - Clock_driver_timecounter_tick(); + Clock_driver_timecounter_tick( arg ); Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE; } @@ -218,7 +234,7 @@ rtems_isr Clock_isr( /* * The driver is one ISR per clock tick. */ - Clock_driver_timecounter_tick(); + Clock_driver_timecounter_tick( arg ); #endif #endif } diff --git a/bsps/shared/dev/clock/xil-ttc.c b/bsps/shared/dev/clock/xil-ttc.c new file mode 100644 index 0000000000..624845d71c --- /dev/null +++ b/bsps/shared/dev/clock/xil-ttc.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSDriverClockXilTTC + * + * @brief This source file contains a Clock Driver implementation using the + * Xilinx Triple Timer Counter (TTC). + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * Copyright (C) 2023 Reflex Aerospace GmbH + * + * Written by Philip Kirkpatrick <p.kirkpatrick@reflexaerospace.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + */ + +#include <bsp.h> +#include <bsp/irq.h> +#include <bsp/fatal.h> +#include <dev/clock/xttcps_hw.h> +#include <rtems/sysinit.h> +#include <rtems/timecounter.h> + +#if XTTCPS_COUNT_VALUE_MASK != UINT32_MAX +#error "unexpected XTTCPS_COUNT_VALUE_MASK value" +#endif + +/** + * @defgroup RTEMSDriverClockXilTTC \ + * Xilinx Triple Timer Counter (TTC) Clock Driver + * + * @ingroup RTEMSDriverClockImpl + * + * @brief This group contains the Xilinx Triple Timer Counter (TTC) Clock + * Driver implementation. + * + * @{ + */ + +uint32_t _CPU_Counter_frequency( void ) +{ + return XIL_CLOCK_TTC_REFERENCE_CLOCK; +} + +CPU_Counter_ticks _CPU_Counter_read(void) +{ + return XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); +} + +static void xil_ttc_initialize(void) +{ + /* Do not use a prescaler to get a high resolution time source */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_CLK_CNTRL_OFFSET, 0); + + /* Disable interupts */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_IER_OFFSET, 0); + + /* + * Enable the timer, do not enable waveform output, increment up, use + * overflow mode, enable match mode. + */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_CNT_CNTRL_OFFSET, + XTTCPS_CNT_CNTRL_EN_WAVE_MASK | XTTCPS_CNT_CNTRL_MATCH_MASK); +} + +RTEMS_SYSINIT_ITEM( + xil_ttc_initialize, + RTEMS_SYSINIT_CPU_COUNTER, + RTEMS_SYSINIT_ORDER_MIDDLE +); + +typedef struct { + struct timecounter base; + uint32_t irq_match_interval; +} xil_ttc_timecounter; + +static xil_ttc_timecounter xil_ttc_clock_instance; + +static uint32_t xil_ttc_get_timecount(struct timecounter *tc) +{ + (void) tc; + return XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); +} + +static void xil_ttc_clock_driver_support_initialize_hardware(void) +{ + xil_ttc_timecounter *tc; + uint64_t frequency; + uint32_t irq_match_interval; + uint32_t count; + + tc = &xil_ttc_clock_instance; + frequency = XIL_CLOCK_TTC_REFERENCE_CLOCK; + irq_match_interval = (uint32_t) + ((frequency * rtems_configuration_get_microseconds_per_tick()) / 1000000); + + /* Setup match register to generate clock interrupts */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, + count + irq_match_interval); + + /* Clear interupts (clear on read) */ + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + + /* Enable interupt for match register */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_IER_OFFSET, + XTTCPS_IXR_MATCH_0_MASK); + + /* Install timecounter */ + tc->irq_match_interval = irq_match_interval; + tc->base.tc_counter_mask = UINT32_MAX; + tc->base.tc_frequency = XIL_CLOCK_TTC_REFERENCE_CLOCK; + tc->base.tc_get_timecount = xil_ttc_get_timecount; + tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&tc->base); +} + +static void xil_ttc_clock_driver_support_at_tick(xil_ttc_timecounter *tc) +{ + uint32_t irq_match_interval; + uint32_t count; + uint32_t match; + + irq_match_interval = tc->irq_match_interval; + + /* Update match register */ + match = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET); + match += irq_match_interval; + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, match); + + /* Clear interupts (clear on read) */ + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + + /* Check that the new match value is in the future */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); + + while (RTEMS_PREDICT_FALSE(match - count > irq_match_interval)) { + /* + * Tick misses may happen if interrupts are disabled for an extremly long + * period or while debugging. + */ + rtems_timecounter_tick(); + + /* Update match register */ + match += irq_match_interval; + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, match); + + /* Clear interupts (clear on read) */ + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + + /* Maybe the new match value is now in the future */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); + } +} + +static rtems_interrupt_entry xil_ttc_interrupt_entry; + +static void xil_ttc_clock_driver_support_install_isr( + rtems_interrupt_handler handler +) +{ + rtems_status_code sc; + + rtems_interrupt_entry_initialize( + &xil_ttc_interrupt_entry, + handler, + &xil_ttc_clock_instance, + "Clock" + ); + sc = rtems_interrupt_entry_install( + XIL_CLOCK_TTC_IRQ, + RTEMS_INTERRUPT_UNIQUE, + &xil_ttc_interrupt_entry + ); + if ( sc != RTEMS_SUCCESSFUL ) { + bsp_fatal(XIL_FATAL_TTC_IRQ_INSTALL); + } +} + +#define Clock_driver_support_at_tick(arg) \ + xil_ttc_clock_driver_support_at_tick(arg) + +#define Clock_driver_support_initialize_hardware \ + xil_ttc_clock_driver_support_initialize_hardware + +#define Clock_driver_support_install_isr(isr) \ + xil_ttc_clock_driver_support_install_isr(isr) + +/** @} */ + +#include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/shared/dev/cpucounter/cpucounterfrequency.c b/bsps/shared/dev/cpucounter/cpucounterfrequency.c index fcc4cdbc33..96a4078889 100644 --- a/bsps/shared/dev/cpucounter/cpucounterfrequency.c +++ b/bsps/shared/dev/cpucounter/cpucounterfrequency.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2018 embedded brains GmbH. All rights reserved. + * Copyright (c) 2018 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/cpucounter/cpucounterread.c b/bsps/shared/dev/cpucounter/cpucounterread.c index f27784f9a7..f4e6e77fc1 100644 --- a/bsps/shared/dev/cpucounter/cpucounterread.c +++ b/bsps/shared/dev/cpucounter/cpucounterread.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/display/disp_fonts.h b/bsps/shared/dev/display/disp_fonts.h index 6705f8d164..e6023721ee 100644 --- a/bsps/shared/dev/display/disp_fonts.h +++ b/bsps/shared/dev/display/disp_fonts.h @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/display/disp_hcms29xx.c b/bsps/shared/dev/display/disp_hcms29xx.c index e22dc10f21..4e221a1a94 100644 --- a/bsps/shared/dev/display/disp_hcms29xx.c +++ b/bsps/shared/dev/display/disp_hcms29xx.c @@ -8,7 +8,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/display/font_hcms29xx.c b/bsps/shared/dev/display/font_hcms29xx.c index a60e665b4b..43596923a8 100644 --- a/bsps/shared/dev/display/font_hcms29xx.c +++ b/bsps/shared/dev/display/font_hcms29xx.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/display/font_hcms29xx.h b/bsps/shared/dev/display/font_hcms29xx.h index ca5e0fd055..d390b9c90b 100644 --- a/bsps/shared/dev/display/font_hcms29xx.h +++ b/bsps/shared/dev/display/font_hcms29xx.h @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/dma/fsl-edma.c b/bsps/shared/dev/dma/fsl-edma.c index b3e1bb2fc5..c8b812c1a5 100644 --- a/bsps/shared/dev/dma/fsl-edma.c +++ b/bsps/shared/dev/dma/fsl-edma.c @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2008-2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,7 +40,7 @@ #include <bsp/fatal.h> #include <bsp/irq.h> #ifdef LIBBSP_ARM_IMXRT_BSP_H -#include <MIMXRT1052.h> +#include <fsl_device_registers.h> #endif #define EDMA_CHANNELS_PER_GROUP 32U diff --git a/bsps/shared/dev/getentropy/getentropy-cpucounter.c b/bsps/shared/dev/getentropy/getentropy-cpucounter.c index d5b2edeb13..44a2573f50 100644 --- a/bsps/shared/dev/getentropy/getentropy-cpucounter.c +++ b/bsps/shared/dev/getentropy/getentropy-cpucounter.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2017 embedded brains GmbH. All rights reserved. + * Copyright (c) 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/cadence-i2c.c b/bsps/shared/dev/i2c/cadence-i2c.c index 91774fb926..67dec0da46 100644 --- a/bsps/shared/dev/i2c/cadence-i2c.c +++ b/bsps/shared/dev/i2c/cadence-i2c.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (C) 2014 embedded brains GmbH + * Copyright (C) 2014 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,7 +28,6 @@ #include <dev/i2c/cadence-i2c.h> #include <dev/i2c/cadence-i2c-regs.h> -#include <rtems/irq-extension.h> #include <rtems/score/assert.h> #include <dev/i2c/i2c.h> diff --git a/bsps/shared/dev/i2c/i2c-sc620.c b/bsps/shared/dev/i2c/i2c-sc620.c index 8840a77f24..ed360086d8 100644 --- a/bsps/shared/dev/i2c/i2c-sc620.c +++ b/bsps/shared/dev/i2c/i2c-sc620.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/spi-flash-m25p40.c b/bsps/shared/dev/i2c/spi-flash-m25p40.c index 66d893cb09..9f6189cd3c 100644 --- a/bsps/shared/dev/i2c/spi-flash-m25p40.c +++ b/bsps/shared/dev/i2c/spi-flash-m25p40.c @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007 embedded brains GmbH. All rights reserved. + * Copyright (c) 2007 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/spi-fram-fm25l256.c b/bsps/shared/dev/i2c/spi-fram-fm25l256.c index f85ac0d4bf..e1ff15e5b3 100644 --- a/bsps/shared/dev/i2c/spi-fram-fm25l256.c +++ b/bsps/shared/dev/i2c/spi-fram-fm25l256.c @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/spi-memdrv.c b/bsps/shared/dev/i2c/spi-memdrv.c index 55460d30a4..d890b9e41a 100644 --- a/bsps/shared/dev/i2c/spi-memdrv.c +++ b/bsps/shared/dev/i2c/spi-memdrv.c @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2008 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/i2c/spi-sd-card.c b/bsps/shared/dev/i2c/spi-sd-card.c index 0375e72be5..36a2721bb9 100644 --- a/bsps/shared/dev/i2c/spi-sd-card.c +++ b/bsps/shared/dev/i2c/spi-sd-card.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008, 2018 embedded brains GmbH + * Copyright (C) 2008, 2018 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/ide/ata_util.c b/bsps/shared/dev/ide/ata_util.c index 68e0f0bbe5..5fd286cdc5 100644 --- a/bsps/shared/dev/ide/ata_util.c +++ b/bsps/shared/dev/ide/ata_util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 embedded brains GmbH. + * Copyright (c) 2010 embedded brains GmbH & Co. KG * * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru> diff --git a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c index 8a1351bbe5..613174bb3a 100644 --- a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c +++ b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c @@ -3,13 +3,14 @@ /** * @file * - * @ingroup RTEMSBSPsShared + * @ingroup DevIRQGIC * - * @brief This source file contains the interrupt get attribute implementation. + * @brief This source file contains the implementation of + * bsp_interrupt_get_attributes() for the GICv2. */ /* - * Copyright (c) 2013, 2021 embedded brains GmbH. All rights reserved. + * Copyright (C) 2013, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c index ee4479155a..bb9bfafb48 100644 --- a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c +++ b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c @@ -3,9 +3,11 @@ /** * @file * - * @ingroup RTEMSBSPsShared + * @ingroup DevIRQGIC * - * @brief This source file contains the interrupt get attribute implementation. + * @brief This source file contains the implementation of + * bsp_interrupt_get_attributes() for the GICv2 of Xilinx Zynq UltraScale+ + * MPSoC and RFSoC devices. */ /* diff --git a/bsps/shared/dev/irq/arm-gicv2.c b/bsps/shared/dev/irq/arm-gicv2.c index 42fed8a762..263278148b 100644 --- a/bsps/shared/dev/irq/arm-gicv2.c +++ b/bsps/shared/dev/irq/arm-gicv2.c @@ -1,7 +1,16 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup DevIRQGIC + * + * @brief This source file contains the implementation of the generic GICv2 + * support. + */ + /* - * Copyright (c) 2013, 2021 embedded brains GmbH. All rights reserved. + * Copyright (C) 2013, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,9 +37,17 @@ #include <dev/irq/arm-gic.h> #include <dev/irq/arm-gic-arch.h> -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/start.h> +#include <rtems/score/processormaskimpl.h> + +/* + * The GIC architecture reserves interrupt ID numbers 1020 to 1023 for special + * purposes. + */ +#if BSP_INTERRUPT_VECTOR_COUNT >= 1020 +#error "BSP_INTERRUPT_VECTOR_COUNT is too large" +#endif #define GIC_CPUIF ((volatile gic_cpuif *) BSP_ARM_GIC_CPUIF_BASE) @@ -66,12 +83,19 @@ void bsp_interrupt_dispatch(void) { volatile gic_cpuif *cpuif = GIC_CPUIF; - uint32_t icciar = cpuif->icciar; - rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); - rtems_vector_number spurious = 1023; - if (vector != spurious) { - arm_interrupt_handler_dispatch(vector); + while (true) { + uint32_t icciar = cpuif->icciar; + rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); + uint32_t status; + + if (!bsp_interrupt_is_valid_vector(vector)) { + break; + } + + status = arm_interrupt_enable_interrupts(); + bsp_interrupt_handler_dispatch_unchecked(vector); + arm_interrupt_restore_interrupts(status); cpuif->icceoir = icciar; } @@ -320,6 +344,7 @@ rtems_status_code arm_gic_irq_get_group( return sc; } +#ifdef RTEMS_SMP rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, const Processor_mask *affinity @@ -379,6 +404,7 @@ rtems_status_code bsp_interrupt_get_affinity( _Processor_mask_From_uint32_t(affinity, targets, 0); return RTEMS_SUCCESSFUL; } +#endif void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets) { @@ -392,9 +418,11 @@ void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets) | GIC_DIST_ICDSGIR_SGIINTID(vector); } +#ifdef RTEMS_SMP uint32_t arm_gic_irq_processor_count(void) { volatile gic_dist *dist = ARM_GIC_DIST; return GIC_DIST_ICDICTR_CPU_NUMBER_GET(dist->icdictr) + 1; } +#endif diff --git a/bsps/shared/dev/irq/arm-gicv3.c b/bsps/shared/dev/irq/arm-gicv3.c index 4772ff5db4..958b1061bd 100644 --- a/bsps/shared/dev/irq/arm-gicv3.c +++ b/bsps/shared/dev/irq/arm-gicv3.c @@ -1,6 +1,15 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup DevIRQGIC * + * @brief This source file contains the implementation of the generic GICv3 + * support. + */ + +/* * Copyright (C) 2019 On-Line Applications Research Corporation (OAR) * * Redistribution and use in source and binary forms, with or without @@ -27,18 +36,24 @@ #include <dev/irq/arm-gicv3.h> -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/start.h> +#include <rtems/score/processormaskimpl.h> void bsp_interrupt_dispatch(void) { - uint32_t icciar = READ_SR(ICC_IAR1); - rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); - rtems_vector_number spurious = 1023; + while (true) { + uint32_t icciar = READ_SR(ICC_IAR1); + rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); + uint32_t status; - if (vector != spurious) { - arm_interrupt_handler_dispatch(vector); + if (!bsp_interrupt_is_valid_vector(vector)) { + break; + } + + status = arm_interrupt_enable_interrupts(); + bsp_interrupt_handler_dispatch_unchecked(vector); + arm_interrupt_restore_interrupts(status); WRITE_SR(ICC_EOIR1, icciar); } @@ -242,6 +257,7 @@ rtems_status_code arm_gic_irq_get_priority( return sc; } +#ifdef RTEMS_SMP rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, const Processor_mask *affinity @@ -274,12 +290,14 @@ rtems_status_code bsp_interrupt_get_affinity( _Processor_mask_From_uint32_t(affinity, targets, 0); return RTEMS_SUCCESSFUL; } +#endif void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets) { gicv3_trigger_sgi(vector, targets); } +#ifdef RTEMS_SMP uint32_t arm_gic_irq_processor_count(void) { volatile gic_dist *dist = ARM_GIC_DIST; @@ -306,3 +324,4 @@ uint32_t arm_gic_irq_processor_count(void) return cpu_count; } +#endif diff --git a/bsps/shared/dev/nand/xnandpsu.c b/bsps/shared/dev/nand/xnandpsu.c index 89451d19f8..79025f3c04 100644 --- a/bsps/shared/dev/nand/xnandpsu.c +++ b/bsps/shared/dev/nand/xnandpsu.c @@ -244,6 +244,11 @@ s32 XNandPsu_CfgInitialize(XNandPsu *InstancePtr, XNandPsu_Config *ConfigPtr, InstancePtr->DmaMode = XNANDPSU_MDMA; InstancePtr->IsReady = XIL_COMPONENT_IS_READY; +#ifdef __rtems__ + /* Set page cache to unavailable */ + InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_UNAVAILABLE; +#endif + /* Initialize the NAND flash targets */ Status = XNandPsu_FlashInit(InstancePtr); if (Status != XST_SUCCESS) { @@ -278,6 +283,11 @@ s32 XNandPsu_CfgInitialize(XNandPsu *InstancePtr, XNandPsu_Config *ConfigPtr, #endif goto Out; } + +#ifdef __rtems__ + /* Set page cache to none */ + InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_NONE; +#endif Out: return Status; } @@ -814,6 +824,21 @@ void XNandPsu_DisableEccMode(XNandPsu *InstancePtr) InstancePtr->EccMode = XNANDPSU_NONE; } +#ifdef __rtems__ +#include <rtems/rtems/clock.h> +static void udelay( void ) +{ + uint64_t time = rtems_clock_get_uptime_nanoseconds() + 1000; + while (1) { + uint64_t newtime = rtems_clock_get_uptime_nanoseconds(); + if (newtime > time) { + break; + } + } +} +#define usleep(x) udelay() +#endif + /*****************************************************************************/ /** * @@ -1439,6 +1464,12 @@ s32 XNandPsu_Write(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *SrcBuf) goto Out; } +#ifdef __rtems__ + if (InstancePtr->PartialDataPageIndex != XNANDPSU_PAGE_CACHE_UNAVAILABLE) { + /* All writes invalidate the page cache */ + InstancePtr->PartialDataPageIndex = XNANDPSU_PAGE_CACHE_NONE; + } +#endif while (LengthVar > 0U) { Block = (u32) (OffsetVar/InstancePtr->Geometry.BlockSize); /* @@ -1467,7 +1498,11 @@ s32 XNandPsu_Write(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *SrcBuf) } Target = (u32) (OffsetVar/InstancePtr->Geometry.TargetSize); +#ifdef __rtems__ + { +#else if (Page > InstancePtr->Geometry.NumTargetPages) { +#endif Page %= InstancePtr->Geometry.NumTargetPages; } @@ -1582,7 +1617,11 @@ s32 XNandPsu_Read(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *DestBuf) } Target = (u32) (OffsetVar/InstancePtr->Geometry.TargetSize); +#ifdef __rtems__ + { +#else if (Page > InstancePtr->Geometry.NumTargetPages) { +#endif Page %= InstancePtr->Geometry.NumTargetPages; } /* Check if partial read */ @@ -1596,14 +1635,45 @@ s32 XNandPsu_Read(XNandPsu *InstancePtr, u64 Offset, u64 Length, u8 *DestBuf) InstancePtr->Geometry.BytesPerPage : (u32)LengthVar; } +#ifdef __rtems__ + if (Page == InstancePtr->PartialDataPageIndex) { + /* + * This is a whole page read for the currently cached + * page. It will not be taken care of below, so perform + * the copy here. + */ + if (PartialBytes == 0U) { + (void)Xil_MemCpy(DestBufPtr, + &InstancePtr->PartialDataBuf[0], + NumBytes); + } + } else { +#endif /* Read page */ Status = XNandPsu_ReadPage(InstancePtr, Target, Page, 0U, BufPtr); +#ifdef __rtems__ + if (PartialBytes > 0U && + InstancePtr->PartialDataPageIndex != XNANDPSU_PAGE_CACHE_UNAVAILABLE) { + /* + * Partial read into page cache. Update the + * cached page index. + */ + InstancePtr->PartialDataPageIndex = Page; + } + } +#endif if (Status != XST_SUCCESS) { goto Out; } if (PartialBytes > 0U) { (void)Xil_MemCpy(DestBufPtr, BufPtr + Col, NumBytes); +#ifdef __rtems__ + /* The destination buffer is touched by hardware, synchronize */ + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheFlushRange((INTPTR)(void *)DestBufPtr, NumBytes); + } +#endif } DestBufPtr += NumBytes; OffsetVar += NumBytes; @@ -1693,13 +1763,21 @@ s32 XNandPsu_Erase(XNandPsu *InstancePtr, u64 Offset, u64 Length) for (Block = StartBlock; Block < (StartBlock + NumBlocks); Block++) { Target = Block/InstancePtr->Geometry.NumTargetBlocks; +#ifdef __rtems__ + u32 ModBlock = Block % InstancePtr->Geometry.NumTargetBlocks; +#else Block %= InstancePtr->Geometry.NumTargetBlocks; +#endif /* Don't erase bad block */ if (XNandPsu_IsBlockBad(InstancePtr, Block) == XST_SUCCESS) continue; /* Block Erase */ +#ifdef __rtems__ + Status = XNandPsu_EraseBlock(InstancePtr, Target, ModBlock); +#else Status = XNandPsu_EraseBlock(InstancePtr, Target, Block); +#endif if (Status != XST_SUCCESS) goto Out; @@ -2002,6 +2080,14 @@ static s32 XNandPsu_ReadPage(XNandPsu *InstancePtr, u32 Target, u32 Page, Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 1); +#ifdef __rtems__ + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } + } +#endif + /* Check ECC Errors */ if (InstancePtr->EccMode == XNANDPSU_HWECC) { /* Hamming Multi Bit Errors */ @@ -2115,6 +2201,14 @@ s32 XNandPsu_ReadSpareBytes(XNandPsu *InstancePtr, u32 Page, u8 *Buf) Status = XNandPsu_Data_ReadWrite(InstancePtr, Buf, PktCount, PktSize, 0, 1); +#ifdef __rtems__ + if (InstancePtr->DmaMode == XNANDPSU_MDMA) { + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheInvalidateRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } + } +#endif + return Status; } @@ -2140,7 +2234,11 @@ s32 XNandPsu_EraseBlock(XNandPsu *InstancePtr, u32 Target, u32 Block) Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertNonvoid(Target < XNANDPSU_MAX_TARGETS); +#ifdef __rtems__ + Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumTargetBlocks); +#else Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks); +#endif s32 Status = XST_FAILURE; u32 Page; @@ -2557,6 +2655,11 @@ static s32 XNandPsu_ChangeWriteColumn(XNandPsu *InstancePtr, u32 Target, if (InstancePtr->DmaMode == XNANDPSU_MDMA) { RegVal = XNANDPSU_INTR_STS_EN_TRANS_COMP_STS_EN_MASK | XNANDPSU_INTR_STS_EN_DMA_INT_STS_EN_MASK; +#ifdef __rtems__ + if (InstancePtr->Config.IsCacheCoherent == 0) { + Xil_DCacheFlushRange((INTPTR)(void *)Buf, (PktSize * PktCount)); + } +#endif XNandPsu_Update_DmaAddr(InstancePtr, Buf); } else { RegVal = XNANDPSU_INTR_STS_EN_BUFF_WR_RDY_STS_EN_MASK; diff --git a/bsps/shared/dev/nand/xnandpsu_bbm.c b/bsps/shared/dev/nand/xnandpsu_bbm.c index dd59148536..40cf798965 100644 --- a/bsps/shared/dev/nand/xnandpsu_bbm.c +++ b/bsps/shared/dev/nand/xnandpsu_bbm.c @@ -62,7 +62,9 @@ static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, static s32 XNandPsu_MarkBbt(XNandPsu* InstancePtr, XNandPsu_BbtDesc *Desc, u32 Target); +#ifndef __rtems__ static s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target); +#endif /************************** Variable Definitions *****************************/ @@ -321,13 +323,23 @@ Out: ******************************************************************************/ static void XNandPsu_ConvertBbt(XNandPsu *InstancePtr, u8 *Buf, u32 Target) { +#ifndef __rtems__ u32 BlockOffset; u8 BlockShift; u32 Data; u8 BlockType; u32 BlockIndex; +#endif u32 BbtLen = InstancePtr->Geometry.NumTargetBlocks >> XNANDPSU_BBT_BLOCK_SHIFT; +#ifdef __rtems__ + u32 BbtOffset = Target * InstancePtr->Geometry.NumTargetBlocks / XNANDPSU_BBT_ENTRY_NUM_BLOCKS; + + for(u32 BbtIndex = 0; BbtIndex < BbtLen; BbtIndex++) { + /* Invert the byte to convert from in-flash BBT to in-memory BBT */ + InstancePtr->Bbt[BbtIndex + BbtOffset] = ~Buf[BbtIndex]; + } +#else u32 StartBlock = Target * InstancePtr->Geometry.NumTargetBlocks; for(BlockOffset = StartBlock; BlockOffset < (StartBlock + BbtLen); @@ -370,6 +382,7 @@ static void XNandPsu_ConvertBbt(XNandPsu *InstancePtr, u8 *Buf, u32 Target) } } } +#endif } /*****************************************************************************/ @@ -400,7 +413,11 @@ static s32 XNandPsu_ReadBbt(XNandPsu *InstancePtr, u32 Target) XNandPsu_BbtDesc *Desc = &InstancePtr->BbtDesc; XNandPsu_BbtDesc *MirrorDesc = &InstancePtr->BbtMirrorDesc; +#ifdef __rtems__ + BufLen = InstancePtr->Geometry.NumTargetBlocks >> +#else BufLen = InstancePtr->Geometry.NumBlocks >> +#endif XNANDPSU_BBT_BLOCK_SHIFT; /* Search the Bad Block Table(BBT) in flash */ Status1 = XNandPsu_SearchBbt(InstancePtr, Desc, Target); @@ -548,6 +565,9 @@ static s32 XNandPsu_SearchBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, VerOffset = Desc->VerOffset; MaxBlocks = Desc->MaxBlocks; SigLength = Desc->SigLength; +#ifdef __rtems__ + Desc->Valid = 0; +#endif /* Read the last 4 blocks for Bad Block Table(BBT) signature */ for(Block = 0U; Block < MaxBlocks; Block++) { @@ -612,6 +632,7 @@ static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, u8 SpareBuf[XNANDPSU_MAX_SPARE_SIZE] __attribute__ ((aligned(64))) = {0U}; #endif +#ifndef __rtems__ u8 Mask[4] = {0x00U, 0x01U, 0x02U, 0x03U}; u8 Data; u32 BlockOffset; @@ -621,11 +642,21 @@ static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, u32 Index; u8 BlockType; u32 BbtLen = InstancePtr->Geometry.NumBlocks >> +#else + s32 Status; + u32 Index; + u32 BbtLen = InstancePtr->Geometry.NumTargetBlocks >> +#endif XNANDPSU_BBT_BLOCK_SHIFT; /* Find a valid block to write the Bad Block Table(BBT) */ if ((!Desc->Valid) != 0U) { for(Index = 0U; Index < Desc->MaxBlocks; Index++) { Block = (EndBlock - Index); +#ifdef __rtems__ + if (XNandPsu_IsBlockBad(InstancePtr, Block) != XST_FAILURE) { + continue; + } +#else BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT; BlockShift = XNandPsu_BbtBlockShift(Block); BlockType = (InstancePtr->Bbt[BlockOffset] >> @@ -639,6 +670,7 @@ static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, /* Good Block */ break; } +#endif Desc->PageOffset[Target] = Block * InstancePtr->Geometry.PagesPerBlock; if (Desc->PageOffset[Target] != @@ -666,6 +698,14 @@ static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, /* Convert the memory based BBT to flash based table */ (void)memset(Buf, 0xff, BbtLen); +#ifdef __rtems__ + u32 BbtTargetOffset = BbtLen * Target; + /* Loop through the BBT entries */ + for(u32 BbtIndex = 0U; BbtIndex < BbtLen; BbtIndex++) { + /* Invert byte to convert from in-memory BBT to in-flash BBT */ + Buf[BbtIndex] = ~InstancePtr->Bbt[BbtIndex + BbtTargetOffset]; + } +#else /* Loop through the number of blocks */ for(BlockOffset = 0U; BlockOffset < BbtLen; BlockOffset++) { Data = InstancePtr->Bbt[BlockOffset]; @@ -679,8 +719,14 @@ static s32 XNandPsu_WriteBbt(XNandPsu *InstancePtr, XNandPsu_BbtDesc *Desc, Data >>= XNANDPSU_BBT_BLOCK_SHIFT; } } +#endif /* Write the Bad Block Table(BBT) to flash */ +#ifdef __rtems__ + Status = XNandPsu_EraseBlock(InstancePtr, Target, + Block % InstancePtr->Geometry.NumTargetBlocks); +#else Status = XNandPsu_EraseBlock(InstancePtr, 0U, Block); +#endif if (Status != XST_SUCCESS) { goto Out; } @@ -726,7 +772,11 @@ Out: * - XST_FAILURE if fail. * ******************************************************************************/ +#ifdef __rtems__ +s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target) +#else static s32 XNandPsu_UpdateBbt(XNandPsu *InstancePtr, u32 Target) +#endif { s32 Status; u8 Version; @@ -786,7 +836,11 @@ static s32 XNandPsu_MarkBbt(XNandPsu* InstancePtr, XNandPsu_BbtDesc *Desc, /* Mark the last four blocks as Reserved */ BlockIndex = ((Target + (u32)1) * InstancePtr->Geometry.NumTargetBlocks) - +#ifdef __rtems__ + Desc->MaxBlocks; +#else Desc->MaxBlocks - (u32)1; +#endif for(Index = 0U; Index < Desc->MaxBlocks; Index++) { @@ -871,11 +925,22 @@ s32 XNandPsu_IsBlockBad(XNandPsu *InstancePtr, u32 Block) * ******************************************************************************/ s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block) +#ifdef __rtems__ +{ + return XNandPsu_MarkBlock(InstancePtr, Block, XNANDPSU_BLOCK_BAD ); +} + +s32 XNandPsu_MarkBlock(XNandPsu *InstancePtr, u32 Block, u8 BlockMark) +#endif { Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY) Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks); +#ifdef __rtems__ + BlockMark &= XNANDPSU_BLOCK_TYPE_MASK; +#endif + u8 Data; u8 BlockShift; u32 BlockOffset; @@ -893,7 +958,11 @@ s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block) /* Mark the block as bad in the RAM based Bad Block Table */ OldVal = Data; Data &= ~(XNANDPSU_BLOCK_TYPE_MASK << BlockShift); +#ifdef __rtems__ + Data |= (BlockMark << BlockShift); +#else Data |= (XNANDPSU_BLOCK_BAD << BlockShift); +#endif NewVal = Data; InstancePtr->Bbt[BlockOffset] = Data; @@ -909,4 +978,24 @@ s32 XNandPsu_MarkBlockBad(XNandPsu *InstancePtr, u32 Block) Out: return Status; } + +#ifdef __rtems__ +bool XNandPsu_StageBlockMark(XNandPsu *InstancePtr, u32 Block, u8 BlockMark) +{ + u8 BlockShift; + u32 BlockOffset; + u8 OldVal; + + BlockMark &= XNANDPSU_BLOCK_TYPE_MASK; + + BlockOffset = Block >> XNANDPSU_BBT_BLOCK_SHIFT; + BlockShift = XNandPsu_BbtBlockShift(Block); + OldVal = InstancePtr->Bbt[BlockOffset] >> BlockShift; + OldVal &= XNANDPSU_BLOCK_TYPE_MASK; + InstancePtr->Bbt[BlockOffset] &= ~(XNANDPSU_BLOCK_TYPE_MASK << BlockShift); + InstancePtr->Bbt[BlockOffset] |= (BlockMark << BlockShift); + return BlockMark != OldVal; +} +#endif + /** @} */ diff --git a/bsps/shared/dev/rtc/mcp7940m.c b/bsps/shared/dev/rtc/mcp7940m.c new file mode 100644 index 0000000000..1abc5faaad --- /dev/null +++ b/bsps/shared/dev/rtc/mcp7940m.c @@ -0,0 +1,361 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2023 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + */ + +/* + * Note: This driver implements only the basic RTC functionality of the + * MCP7940M. It tries not to touch any register fields except for the basic + * date/time fields in the get/set time functions. That way it should be + * possible to re-use the driver for similar RTCs by just replacing the + * initialization function. Suggested method for that: Add a field to the struct + * mcp7940m_rtc with a function pointer that points to the initialization + * function. + * + * All flags that are considered MCP7940M specific have a MCP7940M in the name. + * + * Only 24 hour format is supported. If this driver is the only ones who write + * the RTC, that shouldn't be a problem. + * + * The weekday register is not used. It has a user-defined representation anyway + * and therefore doesn't really matter. + */ + +#include <dev/i2c/i2c.h> +#include <libchip/mcp7940m-rtc.h> +#include <rtems/score/sysstate.h> +#include <rtems/score/todimpl.h> + +#include <fcntl.h> +#include <stdint.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +#define REG_RTCSEC 0x00u + +#define RTCSEC_SECBCD_SHIFT 0u +#define RTCSEC_SECBCD_MASK (0x7fu << RTCSEC_SECBCD_SHIFT) +#define RTCSEC_SECBCD(x) (((x) << RTCSEC_SECBCD_SHIFT) & RTCSEC_SECBCD_MASK) +#define RTCSEC_SECBCD_GET(x) (((x) & RTCSEC_SECBCD_MASK) >> RTCSEC_SECBCD_SHIFT) + +#define MCP7940M_RTCSEC_ST (0x01u << 7) + +#define REG_RTCMIN 0x01 + +#define RTCMIN_MINBCD_SHIFT 0u +#define RTCMIN_MINBCD_MASK (0x7fu << RTCMIN_MINBCD_SHIFT) +#define RTCMIN_MINBCD(x) (((x) << RTCMIN_MINBCD_SHIFT) & RTCMIN_MINBCD_MASK) +#define RTCMIN_MINBCD_GET(x) (((x) & RTCMIN_MINBCD_MASK) >> RTCMIN_MINBCD_SHIFT) + +#define REG_RTCHOUR 0x02 + +#define RTCHOUR_HRBCD12_SHIFT 0u +#define RTCHOUR_HRBCD12_MASK (0x1fu << RTCHOUR_HRBCD12_SHIFT) +#define RTCHOUR_HRBCD12(x) (((x) << RTCHOUR_HRBCD12_SHIFT) & RTCHOUR_HRBCD12_MASK) +#define RTCHOUR_HRBCD12_GET(x) (((x) & RTCHOUR_HRBCD12_MASK) >> RTCHOUR_HRBCD12_SHIFT) + +#define RTCHOUR_HRBCD24_SHIFT 0u +#define RTCHOUR_HRBCD24_MASK (0x3fu << RTCHOUR_HRBCD24_SHIFT) +#define RTCHOUR_HRBCD24(x) (((x) << RTCHOUR_HRBCD24_SHIFT) & RTCHOUR_HRBCD24_MASK) +#define RTCHOUR_HRBCD24_GET(x) (((x) & RTCHOUR_HRBCD24_MASK) >> RTCHOUR_HRBCD24_SHIFT) + +#define RTCHOUR_AMPM (0x01u << 5) +#define RTCHOUR_1224 (0x01u << 6) + +#define REG_RTCWKDAY 0x03 + +#define RTCWKDAY_WKDAY_SHIFT 0u +#define RTCWKDAY_WKDAY_MASK (0x7u << RTCWKDAY_WKDAY_SHIFT) +#define RTCWKDAY_WKDAY(x) (((x) << RTCWKDAY_WKDAY_SHIFT) & RTCWKDAY_WKDAY_MASK) +#define RTCWKDAY_WKDAY_GET(x) (((x) & RTCWKDAY_WKDAY_MASK) >> RTCWKDAY_WKDAY_SHIFT) + +#define REG_RTCDATE 0x04 + +#define RTCDATE_DATEBCD_SHIFT 0u +#define RTCDATE_DATEBCD_MASK (0x3fu << RTCDATE_DATEBCD_SHIFT) +#define RTCDATE_DATEBCD(x) (((x) << RTCDATE_DATEBCD_SHIFT) & RTCDATE_DATEBCD_MASK) +#define RTCDATE_DATEBCD_GET(x) (((x) & RTCDATE_DATEBCD_MASK) >> RTCDATE_DATEBCD_SHIFT) + +#define REG_RTCMTH 0x05 + +#define RTCMTH_MTHBCD_SHIFT 0u +#define RTCMTH_MTHBCD_MASK (0x1fu << RTCMTH_MTHBCD_SHIFT) +#define RTCMTH_MTHBCD(x) (((x) << RTCMTH_MTHBCD_SHIFT) & RTCMTH_MTHBCD_MASK) +#define RTCMTH_MTHBCD_GET(x) (((x) & RTCMTH_MTHBCD_MASK) >> RTCMTH_MTHBCD_SHIFT) + +#define MCP7940M_RTCMTH_LPYR (0x01u << 5) + +#define REG_RTCYEAR 0x06 + +#define RTCYEAR_YRBCD_SHIFT 0u +#define RTCYEAR_YRBCD_MASK (0xffu << RTCYEAR_YRBCD_SHIFT) +#define RTCYEAR_YRBCD(x) (((x) << RTCYEAR_YRBCD_SHIFT) & RTCYEAR_YRBCD_MASK) +#define RTCYEAR_YRBCD_GET(x) (((x) & RTCYEAR_YRBCD_MASK) >> RTCYEAR_YRBCD_SHIFT) + +#define REG_MCP7940M_CONTROL 0x07 + +#define MCP7940M_CONTROL_OUT (0x1u << 7) +#define MCP7940M_CONTROL_SQWEN (0x1u << 6) +#define MCP7940M_CONTROL_ALM1EN (0x1u << 5) +#define MCP7940M_CONTROL_ALM0EN (0x1u << 4) +#define MCP7940M_CONTROL_EXTOSC (0x1u << 3) +#define MCP7940M_CONTROL_CRSTRIM (0x1u << 2) +#define MCP7940M_CONTROL_SQWFS1 (0x1u << 1) +#define MCP7940M_CONTROL_SQWFS0 (0x1u << 0) + +static inline uint8_t bcd_to_bin(uint8_t bcd) +{ + uint8_t bin; + bin = bcd & 0x0f; + bin += ((bcd >> 4) & 0x0f) * 10; + return bin; +} + +static inline uint8_t bin_to_bcd(uint8_t bin) +{ + uint8_t bcd; + bcd = bin % 10; + bcd |= (bin / 10) << 4; + return bcd; +} + +static struct mcp7940m_rtc *mcp7940m_get_context(int minor) +{ + return (struct mcp7940m_rtc *) RTC_Table[minor].pDeviceParams; +} + +static int mcp7940m_i2c_read( + struct mcp7940m_rtc *ctx, + uint8_t addr, + uint8_t *buf, + size_t len +) +{ + int fd; + int rv; + struct i2c_msg msgs[] = {{ + .addr = ctx->i2c_addr, + .flags = 0, + .buf = &addr, + .len = 1, + }, { + .addr = ctx->i2c_addr, + .flags = I2C_M_RD, + .buf = buf, + .len = len, + }}; + struct i2c_rdwr_ioctl_data payload = { + .msgs = msgs, + .nmsgs = sizeof(msgs)/sizeof(msgs[0]), + }; + + fd = open(ctx->i2c_bus_path, O_RDWR); + if (fd < 0) { + return fd; + } + + rv = ioctl(fd, I2C_RDWR, &payload); + + close(fd); + + return rv; +} + +static int mcp7940m_i2c_write( + struct mcp7940m_rtc *ctx, + uint8_t addr, + const uint8_t *buf, + size_t len +) +{ + int fd; + int rv; + uint8_t writebuf[len + 1]; + struct i2c_msg msgs[] = {{ + .addr = ctx->i2c_addr, + .flags = 0, + .buf = writebuf, + .len = len + 1, + }}; + struct i2c_rdwr_ioctl_data payload = { + .msgs = msgs, + .nmsgs = sizeof(msgs)/sizeof(msgs[0]), + }; + + writebuf[0] = addr; + memcpy(&writebuf[1], buf, len); + + fd = open(ctx->i2c_bus_path, O_RDWR); + if (fd < 0) { + return fd; + } + + rv = ioctl(fd, I2C_RDWR, &payload); + + close(fd); + + return rv; +} + +static int mcp7940m_initialize_once(struct mcp7940m_rtc *ctx) +{ + uint8_t reg; + ssize_t rv; + + if (ctx->initialized) { + return 0; + } + + /* + * Make sure that all alarms and outputs are disabled. Enable or disable + * oscillator. + * + * This makes sure that we can start with an uninitialized device that has a + * random value in the control register. + */ + reg = 0; + if (!ctx->crystal) { + reg |= MCP7940M_CONTROL_EXTOSC; + } + rv = mcp7940m_i2c_write(ctx, REG_MCP7940M_CONTROL, ®, 1); + + if (rv == 0 && ctx->crystal) { + rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, ®, 1); + if (rv == 0 && (reg & MCP7940M_RTCSEC_ST) == 0) { + reg |= MCP7940M_RTCSEC_ST; + rv = mcp7940m_i2c_write(ctx, REG_RTCSEC, ®, 1); + } + } + + ctx->initialized = true; + + return rv; +} + +static int mcp7940m_get_time(int minor, rtems_time_of_day *time) +{ + int rv = 0; + uint8_t buf[REG_RTCYEAR + 1]; + struct mcp7940m_rtc *ctx = mcp7940m_get_context(minor); + + if (!_System_state_Is_up(_System_state_Get())) { + return -1; + } + + rtems_mutex_lock(&ctx->mutex); + + rv = mcp7940m_initialize_once(ctx); + + if (rv == 0) { + rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, buf, sizeof(buf)); + } + + if (rv == 0) { + unsigned year = bcd_to_bin(RTCYEAR_YRBCD_GET(buf[REG_RTCYEAR])) + + (TOD_BASE_YEAR / 100 * 100); + if (year < TOD_BASE_YEAR) { + year += 100; + } + time->year = year; + time->month = bcd_to_bin(RTCMTH_MTHBCD_GET(buf[REG_RTCMTH])); + time->day = bcd_to_bin(RTCDATE_DATEBCD_GET(buf[REG_RTCDATE])); + time->hour = bcd_to_bin(RTCHOUR_HRBCD24_GET(buf[REG_RTCHOUR])); + time->minute = bcd_to_bin(RTCMIN_MINBCD_GET(buf[REG_RTCMIN])); + time->second = bcd_to_bin(RTCSEC_SECBCD_GET(buf[REG_RTCSEC])); + time->ticks = 0; + } + + rtems_mutex_unlock(&ctx->mutex); + + return rv; +} + +static int mcp7940m_set_time(int minor, const rtems_time_of_day *time) +{ + int rv = 0; + uint8_t buf[REG_RTCYEAR + 1]; + struct mcp7940m_rtc *ctx = mcp7940m_get_context(minor); + + if (!_System_state_Is_up(_System_state_Get())) { + return -1; + } + + rtems_mutex_lock(&ctx->mutex); + + rv = mcp7940m_initialize_once(ctx); + + if (rv == 0) { + rv = mcp7940m_i2c_read(ctx, REG_RTCSEC, buf, sizeof(buf)); + } + + if (rv == 0) { + /* Make sure weekday is not 0 (out of range). Otherwise it's not used. */ + if (RTCWKDAY_WKDAY_GET(buf[REG_RTCWKDAY]) < 1) { + buf[REG_RTCWKDAY] &= ~RTCWKDAY_WKDAY_MASK; + buf[REG_RTCWKDAY] |= RTCWKDAY_WKDAY(1); + } + + buf[REG_RTCYEAR] &= ~RTCYEAR_YRBCD_MASK; + buf[REG_RTCYEAR] |= RTCYEAR_YRBCD(bin_to_bcd(time->year % 100)); + + buf[REG_RTCMTH] &= ~RTCMTH_MTHBCD_MASK; + buf[REG_RTCMTH] |= RTCMTH_MTHBCD(bin_to_bcd(time->month)); + + buf[REG_RTCDATE] &= ~RTCDATE_DATEBCD_MASK; + buf[REG_RTCDATE] |= RTCDATE_DATEBCD(bin_to_bcd(time->day)); + + buf[REG_RTCHOUR] &= ~(RTCHOUR_HRBCD24_MASK | RTCHOUR_1224); + buf[REG_RTCHOUR] |= RTCHOUR_HRBCD24(bin_to_bcd(time->hour)); + + buf[REG_RTCMIN] &= ~RTCMIN_MINBCD_MASK; + buf[REG_RTCMIN] |= RTCMIN_MINBCD(bin_to_bcd(time->minute)); + + buf[REG_RTCSEC] &= ~RTCSEC_SECBCD_MASK; + buf[REG_RTCSEC] |= RTCSEC_SECBCD(bin_to_bcd(time->second)); + + rv = mcp7940m_i2c_write(ctx, REG_RTCSEC, buf, sizeof(buf)); + } + + rtems_mutex_unlock(&ctx->mutex); + + return rv; +} + +static void mcp7940m_init(int minor) +{ + (void) minor; +} + +bool rtc_mcp7940m_probe(int minor) +{ + return true; +} + +const rtc_fns rtc_mcp7940m_fns = { + .deviceInitialize = mcp7940m_init, + .deviceGetTime = mcp7940m_get_time, + .deviceSetTime = mcp7940m_set_time, +}; diff --git a/bsps/shared/dev/serial/arm-pl011.c b/bsps/shared/dev/serial/arm-pl011.c index f0e7031f96..e9a8e3f5a4 100644 --- a/bsps/shared/dev/serial/arm-pl011.c +++ b/bsps/shared/dev/serial/arm-pl011.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. + * Copyright (C) 2013, 2014 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/console-output-char.c b/bsps/shared/dev/serial/console-output-char.c index 14ad05cd8c..477fd1ffde 100644 --- a/bsps/shared/dev/serial/console-output-char.c +++ b/bsps/shared/dev/serial/console-output-char.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/console-polled.c b/bsps/shared/dev/serial/console-polled.c index 0fc765cb64..37ad5b8f18 100644 --- a/bsps/shared/dev/serial/console-polled.c +++ b/bsps/shared/dev/serial/console-polled.c @@ -113,7 +113,7 @@ rtems_device_driver console_open( NULL, /* setAttributes */ NULL, /* stopRemoteTx */ NULL, /* startRemoteTx */ - 0 /* outputUsesInterrupts */ + TERMIOS_POLLED /* outputUsesInterrupts */ }; assert( minor == 0 ); diff --git a/bsps/shared/dev/serial/console-termios-init.c b/bsps/shared/dev/serial/console-termios-init.c index da3eeaa2a7..c144549cb4 100644 --- a/bsps/shared/dev/serial/console-termios-init.c +++ b/bsps/shared/dev/serial/console-termios-init.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * Copyright (C) 2014, 2016 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/console-termios.c b/bsps/shared/dev/serial/console-termios.c index 16d5344be1..bdea1a0284 100644 --- a/bsps/shared/dev/serial/console-termios.c +++ b/bsps/shared/dev/serial/console-termios.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * Copyright (C) 2014, 2016 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/getserialmouseps2.c b/bsps/shared/dev/serial/getserialmouseps2.c index 22def46749..451a62d716 100644 --- a/bsps/shared/dev/serial/getserialmouseps2.c +++ b/bsps/shared/dev/serial/getserialmouseps2.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/legacy-console.c b/bsps/shared/dev/serial/legacy-console.c index 7da87276b0..698439b247 100644 --- a/bsps/shared/dev/serial/legacy-console.c +++ b/bsps/shared/dev/serial/legacy-console.c @@ -234,7 +234,11 @@ rtems_device_driver console_open( Callbacks.stopRemoteTx = NULL; Callbacks.startRemoteTx = NULL; } - Callbacks.outputUsesInterrupts = cptr->pDeviceFns->deviceOutputUsesInterrupts; + if (cptr->pDeviceFns->deviceOutputUsesInterrupts) { + Callbacks.outputUsesInterrupts = TERMIOS_IRQ_DRIVEN; + } else { + Callbacks.outputUsesInterrupts = TERMIOS_POLLED; + } /* XXX what about * Console_Port_Tbl[minor].ulMargin, diff --git a/bsps/shared/dev/serial/uart-output-char.c b/bsps/shared/dev/serial/uart-output-char.c index 632aec26c3..6ec58a6588 100644 --- a/bsps/shared/dev/serial/uart-output-char.c +++ b/bsps/shared/dev/serial/uart-output-char.c @@ -9,7 +9,7 @@ */ /* - * Copyright (c) 2010-2011 embedded brains GmbH. All rights reserved. + * Copyright (C) 2010, 2011 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/dev/serial/zynq-uart-kernel-io.c b/bsps/shared/dev/serial/zynq-uart-kernel-io.c new file mode 100644 index 0000000000..61b1043cd2 --- /dev/null +++ b/bsps/shared/dev/serial/zynq-uart-kernel-io.c @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup zynq_uart + * + * @brief This source file contains the definition of ::BSP_output_char and + * ::BSP_poll_char. + */ + +/* + * Copyright (C) 2013, 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + */ + +#include <rtems/bspIo.h> + +#include <bsp.h> +#include <dev/serial/zynq-uart-regs.h> +#include <rtems/sysinit.h> + +static void zynq_uart_kernel_output_char(char c) +{ + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; + + zynq_uart_write_char_polled(regs, c); +} + +static int zynq_uart_kernel_poll_char(void) +{ + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; + + return zynq_uart_read_char_polled(regs); +} + +static void zynq_uart_kernel_early_init(char c); + +static void zynq_uart_kernel_init(void) +{ + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; + + if (BSP_output_char != zynq_uart_kernel_early_init) { + return; + } + + zynq_uart_initialize(regs); + BSP_output_char = zynq_uart_kernel_output_char; +} + +static void zynq_uart_kernel_early_init(char c) +{ + zynq_uart_kernel_init(); + zynq_uart_kernel_output_char(c); +} + +BSP_output_char_function_type BSP_output_char = zynq_uart_kernel_early_init; + +BSP_polling_getchar_function_type BSP_poll_char = zynq_uart_kernel_poll_char; + +RTEMS_SYSINIT_ITEM( + zynq_uart_kernel_init, + RTEMS_SYSINIT_BSP_START, + RTEMS_SYSINIT_ORDER_LAST_BUT_5 +); diff --git a/bsps/shared/dev/serial/zynq-uart-polled.c b/bsps/shared/dev/serial/zynq-uart-polled.c index 6865fa8d6f..dbf75539f6 100644 --- a/bsps/shared/dev/serial/zynq-uart-polled.c +++ b/bsps/shared/dev/serial/zynq-uart-polled.c @@ -1,7 +1,16 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file * - * Copyright (C) 2013, 2017 embedded brains GmbH + * @ingroup RTEMSBSPsARMZynq + * + * @brief This source file contains the implementation of the polled Zynq UART + * support. + */ + +/* + * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -115,10 +124,8 @@ int zynq_cal_baud_rate(uint32_t baudrate, return 0; } -void zynq_uart_initialize(rtems_termios_device_context *base) +void zynq_uart_initialize(volatile zynq_uart *regs) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; uint32_t brgr = 0x3e; uint32_t bauddiv = 0x6; uint32_t mode_clks = regs->mode & ZYNQ_UART_MODE_CLKS; @@ -145,18 +152,15 @@ void zynq_uart_initialize(rtems_termios_device_context *base) | ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8) | mode_clks; - while (zynq_uart_read_polled(base) >= 0) { + while (zynq_uart_read_char_polled(regs) >= 0) { /* Drop */ } - zynq_uart_reset_tx_flush(ctx); + zynq_uart_reset_tx_flush(regs); } -int zynq_uart_read_polled(rtems_termios_device_context *base) +int zynq_uart_read_char_polled(volatile zynq_uart *regs) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) { return -1; } else { @@ -164,14 +168,8 @@ int zynq_uart_read_polled(rtems_termios_device_context *base) } } -void zynq_uart_write_polled( - rtems_termios_device_context *base, - char c -) +void zynq_uart_write_char_polled(volatile zynq_uart *regs, char c) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TNFUL) != 0) { /* Wait */ } @@ -179,13 +177,12 @@ void zynq_uart_write_polled( regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c); } -void zynq_uart_reset_tx_flush(zynq_uart_context *ctx) +void zynq_uart_reset_tx_flush(volatile zynq_uart *regs) { - volatile zynq_uart *regs = ctx->regs; - int c = 4; + int c = 4; while (c-- > 0) - zynq_uart_write_polled(&ctx->base, '\r'); + zynq_uart_write_char_polled(regs, '\r'); while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0 || (regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TACTIVE) != 0) { diff --git a/bsps/shared/dev/serial/zynq-uart.c b/bsps/shared/dev/serial/zynq-uart.c index 8ff1d25da0..0489288271 100644 --- a/bsps/shared/dev/serial/zynq-uart.c +++ b/bsps/shared/dev/serial/zynq-uart.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: BSD-2-Clause * - * Copyright (C) 2013, 2017 embedded brains GmbH + * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,6 +28,7 @@ #include <dev/serial/zynq-uart.h> #include <dev/serial/zynq-uart-regs.h> #include <bsp/irq.h> +#include <rtems/termiostypes.h> #include <bspopts.h> @@ -66,14 +67,14 @@ static bool zynq_uart_first_open( rtems_libio_open_close_args_t *args ) { -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS zynq_uart_context *ctx = (zynq_uart_context *) base; volatile zynq_uart *regs = ctx->regs; +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS rtems_status_code sc; #endif rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD); - zynq_uart_initialize(base); + zynq_uart_initialize(regs); #ifdef ZYNQ_CONSOLE_USE_INTERRUPTS regs->rx_fifo_trg_lvl = 1; @@ -108,15 +109,23 @@ static void zynq_uart_last_close( } #endif +#ifndef ZYNQ_CONSOLE_USE_INTERRUPTS +static int zynq_uart_read_polled(rtems_termios_device_context *base) +{ + zynq_uart_context *ctx = (zynq_uart_context *) base; + return zynq_uart_read_char_polled(ctx->regs); +} +#endif + static void zynq_uart_write_support( rtems_termios_device_context *base, const char *buf, size_t len ) { -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS zynq_uart_context *ctx = (zynq_uart_context *) base; volatile zynq_uart *regs = ctx->regs; +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS regs->irq_dis = ZYNQ_UART_TEMPTY; @@ -134,9 +143,9 @@ static void zynq_uart_write_support( regs->irq_en = ZYNQ_UART_TEMPTY; } #else - ssize_t i; + size_t i; for (i = 0; i < len; ++i) { - zynq_uart_write_polled(base, buf[i]); + zynq_uart_write_char_polled(regs, buf[i]); } #endif } diff --git a/bsps/shared/dev/spi/xqspipsu-flash-helper.c b/bsps/shared/dev/spi/xqspipsu-flash-helper.c index 7fa04efdde..10e1066173 100644 --- a/bsps/shared/dev/spi/xqspipsu-flash-helper.c +++ b/bsps/shared/dev/spi/xqspipsu-flash-helper.c @@ -274,22 +274,57 @@ static void QspiPsuHandler( } } -/*****************************************************************************/ -/** - * - * Reads the flash ID and identifies the flash in FCT table. - * - * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. - * - * @return XST_SUCCESS if successful, else XST_FAILURE. - * - * @note None. - * - *****************************************************************************/ -static int FlashReadID(XQspiPsu *QspiPsuPtr) +int QspiPsu_NOR_RDSFDP( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 **ReadBfrPtr +) +{ + int Status; + + *ReadBfrPtr = ReadBuffer; + + CmdBfr[COMMAND_OFFSET] = READ_SFDP; + CmdBfr[ADDRESS_1_OFFSET] = + (u8)((Address & 0xFF0000) >> 16); + CmdBfr[ADDRESS_2_OFFSET] = + (u8)((Address & 0xFF00) >> 8); + CmdBfr[ADDRESS_3_OFFSET] = + (u8)(Address & 0xFF); + + FlashMsg[0].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[0].TxBfrPtr = CmdBfr; + FlashMsg[0].RxBfrPtr = NULL; + FlashMsg[0].ByteCount = 4; + FlashMsg[0].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[1].TxBfrPtr = NULL; + FlashMsg[1].RxBfrPtr = NULL; + FlashMsg[1].ByteCount = DUMMY_CLOCKS; + FlashMsg[1].Flags = 0; + + FlashMsg[2].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[2].TxBfrPtr = NULL; + FlashMsg[2].RxBfrPtr = *ReadBfrPtr; + FlashMsg[2].ByteCount = ByteCount; + FlashMsg[2].Flags = XQSPIPSU_MSG_FLAG_RX; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, 3); + if (Status != XST_SUCCESS) + return XST_FAILURE; + + while (TransferInProgress); + + rtems_cache_invalidate_multiple_data_lines(ReadBuffer, ByteCount); + return 0; +} + +int QspiPsu_NOR_RDID(XQspiPsu *QspiPsuPtr, u8 *ReadBfrPtr, u32 ReadLen) { int Status; - u32 ReadId = 0; /* * Read ID @@ -303,7 +338,7 @@ static int FlashReadID(XQspiPsu *QspiPsuPtr) FlashMsg[1].TxBfrPtr = NULL; FlashMsg[1].RxBfrPtr = ReadBfrPtr; - FlashMsg[1].ByteCount = 3; + FlashMsg[1].ByteCount = ReadLen; FlashMsg[1].BusWidth = XQSPIPSU_SELECT_MODE_SPI; FlashMsg[1].Flags = XQSPIPSU_MSG_FLAG_RX; @@ -314,6 +349,33 @@ static int FlashReadID(XQspiPsu *QspiPsuPtr) } while (TransferInProgress); + rtems_cache_invalidate_multiple_data_lines(ReadBfrPtr, ReadLen); + return XST_SUCCESS; +} + +/*****************************************************************************/ +/** + * + * Reads the flash ID and identifies the flash in FCT table. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * + * @return XST_SUCCESS if successful, else XST_FAILURE. + * + * @note None. + * + *****************************************************************************/ +static int FlashReadID(XQspiPsu *QspiPsuPtr) +{ + u32 ReadId = 0; + u32 ReadLen = 3; + int Status; + + Status = QspiPsu_NOR_RDID(QspiPsuPtr, ReadBfrPtr, ReadLen); + if (Status != XST_SUCCESS) { + return XST_FAILURE; + } + /* In case of dual, read both and ensure they are same make/size */ /* @@ -333,7 +395,7 @@ static int FlashReadID(XQspiPsu *QspiPsuPtr) return XST_SUCCESS; } -int QspiPsu_NOR_Write( +int QspiPsu_NOR_Write_Page( XQspiPsu *QspiPsuPtr, u32 Address, u32 ByteCount, @@ -475,6 +537,51 @@ int QspiPsu_NOR_Write( return 0; } +int QspiPsu_NOR_Write( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 *WriteBfrPtr +) +{ + int Status; + size_t ByteCountRemaining = ByteCount; + unsigned char *WriteBfrPartial = WriteBfrPtr; + uint32_t AddressPartial = Address; + uint32_t PageSize = Flash_Config_Table[FCTIndex].PageSize; + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { + PageSize *= 2; + } + + while (ByteCountRemaining > 0) { + /* Get write boundary */ + size_t WriteChunkLen = RTEMS_ALIGN_UP(AddressPartial + 1, PageSize); + + /* Get offset to write boundary */ + WriteChunkLen -= (size_t)AddressPartial; + + /* Cap short writes */ + if (WriteChunkLen > ByteCountRemaining) { + WriteChunkLen = ByteCountRemaining; + } + + Status = QspiPsu_NOR_Write_Page( + QspiPsuPtr, + AddressPartial, + WriteChunkLen, + WriteBfrPartial + ); + if ( Status != XST_SUCCESS ) { + return Status; + } + + ByteCountRemaining -= WriteChunkLen; + AddressPartial += WriteChunkLen; + WriteBfrPartial += WriteChunkLen; + } + return Status; +} + int QspiPsu_NOR_Erase( XQspiPsu *QspiPsuPtr, u32 Address, @@ -489,22 +596,18 @@ int QspiPsu_NOR_Erase( u32 NumSect; int Status; u32 SectSize; - u32 SectMask; WriteEnableCmd = WRITE_ENABLE_CMD; if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { - SectMask = (Flash_Config_Table[FCTIndex]).SectMask - (Flash_Config_Table[FCTIndex]).SectSize; SectSize = (Flash_Config_Table[FCTIndex]).SectSize * 2; NumSect = (Flash_Config_Table[FCTIndex]).NumSect; } else if (QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED) { NumSect = (Flash_Config_Table[FCTIndex]).NumSect * 2; - SectMask = (Flash_Config_Table[FCTIndex]).SectMask; SectSize = (Flash_Config_Table[FCTIndex]).SectSize; } else { SectSize = (Flash_Config_Table[FCTIndex]).SectSize; NumSect = (Flash_Config_Table[FCTIndex]).NumSect; - SectMask = (Flash_Config_Table[FCTIndex]).SectMask; } /* @@ -569,18 +672,9 @@ int QspiPsu_NOR_Erase( /* * Calculate no. of sectors to erase based on byte count */ - NumSect = (ByteCount / SectSize) + 1; - - /* - * If ByteCount to k sectors, - * but the address range spans from N to N+k+1 sectors, then - * increment no. of sectors to be erased - */ - - if (((Address + ByteCount) & SectMask) == - ((Address + (NumSect * SectSize)) & SectMask)) { - NumSect++; - } + u32 SectorStartBase = RTEMS_ALIGN_DOWN(Address, SectSize); + u32 SectorEndTop = RTEMS_ALIGN_UP(Address + ByteCount, SectSize); + NumSect = (SectorEndTop - SectorStartBase)/SectSize; for (Sector = 0; Sector < NumSect; Sector++) { @@ -828,6 +922,7 @@ int QspiPsu_NOR_Read( while (TransferInProgress); } + rtems_cache_invalidate_multiple_data_lines(ReadBuffer, ByteCount); return 0; } @@ -1015,6 +1110,7 @@ static int MultiDieRead( Address += data_len; remain_len -= data_len; } + rtems_cache_invalidate_multiple_data_lines(ReadBfrPtr, ByteCount); return 0; } @@ -2003,3 +2099,243 @@ static int FlashEnableQuadMode(XQspiPsu *QspiPsuPtr) return Status; } + +static int MultiDieReadEcc( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 *WriteBfrPtr, + u8 *ReadBfrPtr +); + +int QspiPsu_NOR_Read_Ecc( + XQspiPsu *QspiPsuPtr, + u32 Address, + u8 *ReadBfrPtr +) +{ + u32 RealAddr; + u32 DiscardByteCnt; + u32 FlashMsgCnt; + u8 EccBuffer[16]; + int ByteCount = sizeof(EccBuffer); + int Status; + + /* Check die boundary conditions if required for any flash */ + if (Flash_Config_Table[FCTIndex].NumDie > 1) { + + Status = MultiDieReadEcc(QspiPsuPtr, Address, ByteCount, + CmdBfr, EccBuffer); + if (Status == XST_SUCCESS) { + /* All bytes are the same, so copy one return byte into the output buffer */ + *ReadBfrPtr = EccBuffer[0]; + } + return Status; + } + + /* For Dual Stacked, split and read for boundary crossing */ + /* + * Translate address based on type of connection + * If stacked assert the slave select based on address + */ + RealAddr = GetRealAddr(QspiPsuPtr, Address); + + CmdBfr[COMMAND_OFFSET] = READ_ECCSR; + CmdBfr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + CmdBfr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + CmdBfr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + CmdBfr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xF0); + DiscardByteCnt = 5; + + FlashMsgCnt = 0; + + FlashMsg[FlashMsgCnt].TxBfrPtr = CmdBfr; + FlashMsg[FlashMsgCnt].RxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].ByteCount = DiscardByteCnt; + FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsgCnt++; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].ByteCount = DUMMY_CLOCKS; + FlashMsg[FlashMsgCnt].Flags = 0; + + FlashMsgCnt++; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = EccBuffer; + FlashMsg[FlashMsgCnt].ByteCount = ByteCount; + FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX; + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) { + FlashMsg[FlashMsgCnt].Flags |= XQSPIPSU_MSG_FLAG_STRIPE; + } + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, + FlashMsgCnt + 1); + if (Status == XST_SUCCESS) { + while (TransferInProgress); + + /* All bytes are the same, so copy one return byte into the output buffer */ + *ReadBfrPtr = EccBuffer[0]; + } + + return Status; +} + +/*****************************************************************************/ +/** + * + * This function performs an ECC read operation for multi die flash devices. + * Default setting is in DMA mode. + * + * @param QspiPsuPtr is a pointer to the QSPIPSU driver component to use. + * @param Address contains the address of the first sector which needs to + * be erased. + * @param ByteCount contains the total size to be erased. + * @param WriteBfrPtr is pointer to the write buffer which contains data to be + * transmitted + * @param ReadBfrPtr is pointer to the read buffer to which valid received data + * should be written + * + * @return XST_SUCCESS if successful, else XST_FAILURE. + * + * @note None. + * + ******************************************************************************/ +static int MultiDieReadEcc( + XQspiPsu *QspiPsuPtr, + u32 Address, + u32 ByteCount, + u8 *WriteBfrPtr, + u8 *ReadBuffer +) +{ + u32 RealAddr; + u32 DiscardByteCnt; + u32 FlashMsgCnt; + int Status; + u32 cur_bank = 0; + u32 nxt_bank = 0; + u32 bank_size; + u32 remain_len = ByteCount; + u32 data_len; + u32 transfer_len; + + /* + * Some flash devices like N25Q512 have multiple dies + * in it. Read operation in these devices is bounded + * by its die segment. In a continuous read, across + * multiple dies, when the last byte of the selected + * die segment is read, the next byte read is the + * first byte of the same die segment. This is Die + * cross over issue. So to handle this issue, split + * a read transaction, that spans across multiple + * banks, into one read per bank. Bank size is 16MB + * for single and dual stacked mode and 32MB for dual + * parallel mode. + */ + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) + bank_size = SIXTEENMB << 1; + else + bank_size = SIXTEENMB; + + while (remain_len) { + cur_bank = Address / bank_size; + nxt_bank = (Address + remain_len) / bank_size; + + if (cur_bank != nxt_bank) { + transfer_len = (bank_size * (cur_bank + 1)) - Address; + if (remain_len < transfer_len) + data_len = remain_len; + else + data_len = transfer_len; + } else { + data_len = remain_len; + } + /* + * Translate address based on type of connection + * If stacked assert the slave select based on address + */ + RealAddr = GetRealAddr(QspiPsuPtr, Address); + + WriteBfrPtr[COMMAND_OFFSET] = READ_ECCSR; + WriteBfrPtr[ADDRESS_1_OFFSET] = + (u8)((RealAddr & 0xFF000000) >> 24); + WriteBfrPtr[ADDRESS_2_OFFSET] = + (u8)((RealAddr & 0xFF0000) >> 16); + WriteBfrPtr[ADDRESS_3_OFFSET] = + (u8)((RealAddr & 0xFF00) >> 8); + WriteBfrPtr[ADDRESS_4_OFFSET] = + (u8)(RealAddr & 0xF0); + DiscardByteCnt = 5; + + FlashMsgCnt = 0; + + FlashMsg[FlashMsgCnt].TxBfrPtr = WriteBfrPtr; + FlashMsg[FlashMsgCnt].RxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].ByteCount = DiscardByteCnt; + FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_TX; + + FlashMsgCnt++; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].ByteCount = DUMMY_CLOCKS; + FlashMsg[FlashMsgCnt].Flags = 0; + + FlashMsgCnt++; + + FlashMsg[FlashMsgCnt].TxBfrPtr = NULL; + FlashMsg[FlashMsgCnt].RxBfrPtr = ReadBuffer; + FlashMsg[FlashMsgCnt].ByteCount = data_len; + FlashMsg[FlashMsgCnt].BusWidth = XQSPIPSU_SELECT_MODE_SPI; + FlashMsg[FlashMsgCnt].Flags = XQSPIPSU_MSG_FLAG_RX; + + if (QspiPsuPtr->Config.ConnectionMode == + XQSPIPSU_CONNECTION_MODE_PARALLEL) + FlashMsg[FlashMsgCnt].Flags |= + XQSPIPSU_MSG_FLAG_STRIPE; + + TransferInProgress = TRUE; + Status = XQspiPsu_InterruptTransfer(QspiPsuPtr, FlashMsg, + FlashMsgCnt + 1); + if (Status != XST_SUCCESS) + return XST_FAILURE; + + while (TransferInProgress); + + ReadBuffer += data_len; + Address += data_len; + remain_len -= data_len; + } + return 0; +} + +u32 QspiPsu_NOR_Get_Sector_Size(XQspiPsu *QspiPsuPtr) +{ + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { + return Flash_Config_Table[FCTIndex].SectSize * 2; + } + return Flash_Config_Table[FCTIndex].SectSize; +} + +u32 QspiPsu_NOR_Get_Device_Size(XQspiPsu *QspiPsuPtr) +{ + if(QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_STACKED + || QspiPsuPtr->Config.ConnectionMode == XQSPIPSU_CONNECTION_MODE_PARALLEL) { + return Flash_Config_Table[FCTIndex].FlashDeviceSize * 2; + } + return Flash_Config_Table[FCTIndex].FlashDeviceSize; +} diff --git a/bsps/shared/dev/spi/xqspipsu.c b/bsps/shared/dev/spi/xqspipsu.c index 1286efd359..93d3fa4c98 100644 --- a/bsps/shared/dev/spi/xqspipsu.c +++ b/bsps/shared/dev/spi/xqspipsu.c @@ -84,6 +84,9 @@ #include "xqspipsu.h" #include "xqspipsu_control.h" #include "sleep.h" +#ifdef __rtems__ +#include <rtems/rtems/cache.h> +#endif /************************** Constant Definitions *****************************/ #define MAX_DELAY_CNT 10000000U /**< Max delay count */ @@ -275,6 +278,12 @@ void XQspiPsu_Abort(XQspiPsu *InstancePtr) u32 IntrStatus, ConfigReg, FifoStatus; u32 DelayCount = 0U; +#ifdef __rtems__ + u32 FifoStatusMask = XQSPIPSU_ISR_RXEMPTY_MASK; + FifoStatusMask |= XQSPIPSU_ISR_TXEMPTY_MASK; + FifoStatusMask |= XQSPIPSU_ISR_GENFIFOEMPTY_MASK; +#endif + Xil_AssertVoid(InstancePtr != NULL); #ifdef DEBUG xil_printf("\nXQspiPsu_Abort\r\n"); @@ -326,8 +335,13 @@ void XQspiPsu_Abort(XQspiPsu *InstancePtr) */ FifoStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, +#ifdef __rtems__ + XQSPIPSU_ISR_OFFSET) & FifoStatusMask; + while(FifoStatus != FifoStatusMask) { +#else XQSPIPSU_FIFO_CTRL_OFFSET); while(FifoStatus != 0U) { +#endif if (DelayCount == MAX_DELAY_CNT) { #ifdef DEBUG xil_printf("Timeout error, FIFO reset failed.\r\n"); @@ -337,7 +351,11 @@ void XQspiPsu_Abort(XQspiPsu *InstancePtr) usleep(1); DelayCount++; FifoStatus = XQspiPsu_ReadReg(InstancePtr->Config.BaseAddress, +#ifdef __rtems__ + XQSPIPSU_ISR_OFFSET) & FifoStatusMask; +#else XQSPIPSU_FIFO_CTRL_OFFSET); +#endif } } @@ -442,7 +460,16 @@ s32 XQspiPsu_PolledTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, for (Index = 0; Index < (s32)NumMsg; Index++) { Xil_AssertNonvoid(Msg[Index].ByteCount > 0U); +#ifdef __rtems__ + if (Msg[Index].TxBfrPtr != NULL) { + rtems_cache_flush_multiple_data_lines(Msg[Index].TxBfrPtr, Msg[Index].ByteCount); + } +#endif } +#ifdef __rtems__ + rtems_cache_flush_multiple_data_lines(Msg, NumMsg * sizeof(*Msg)); +#endif + /* * Check whether there is another transfer in progress. * Not thread-safe @@ -582,7 +609,18 @@ s32 XQspiPsu_InterruptTransfer(XQspiPsu *InstancePtr, XQspiPsu_Msg *Msg, Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); for (Index = 0; Index < (s32)NumMsg; Index++) +#ifdef __rtems__ + { +#endif Xil_AssertNonvoid(Msg[Index].ByteCount > 0U); +#ifdef __rtems__ + if (Msg[Index].TxBfrPtr != NULL) { + rtems_cache_flush_multiple_data_lines(Msg[Index].TxBfrPtr, Msg[Index].ByteCount); + } + } + rtems_cache_flush_multiple_data_lines(Msg, NumMsg * sizeof(*Msg)); +#endif + /* * Check whether there is another transfer in progress. * Not thread-safe diff --git a/bsps/shared/doxygen.h b/bsps/shared/doxygen.h index d3679c2f3d..be681673d0 100644 --- a/bsps/shared/doxygen.h +++ b/bsps/shared/doxygen.h @@ -1,4 +1,12 @@ /** + * @file + * + * @ingroup RTEMSImplDoxygen + * + * @brief This header file defines BSP-specific groups. + */ + +/** * @defgroup RTEMSBSPs Board Support Packages * * @brief This group contains the Board Support Packages (BSPs). diff --git a/bsps/shared/freebsd/stand/efi/include/README b/bsps/shared/freebsd/stand/efi/include/README new file mode 100644 index 0000000000..bf821fae7e --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/README @@ -0,0 +1,36 @@ +/* $FreeBSD$ */ +/*- + +Files in this directory and subdirectories are subject to the following +copyright unless superceded or supplemented by additional specific license +terms found in the file headers of individual files. + +Copyright (c) 1998-2000 Intel Corporation + +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 ``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 INTEL 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. THE EFI SPECIFICATION AND ALL +OTHER INFORMATION ON THIS WEB SITE ARE PROVIDED "AS IS" WITH NO +WARRANTIES, AND ARE SUBJECT TO CHANGE WITHOUT NOTICE. + +*/ diff --git a/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h b/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h new file mode 100644 index 0000000000..97b4a04865 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/amd64/efibind.h @@ -0,0 +1,275 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efefind.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +#pragma pack() + + +#ifdef __FreeBSD__ +#include <sys/stdint.h> +#elif __rtems__ +#include <stdint.h> +#else +// +// Basic int types of various widths +// + +#if (__STDC_VERSION__ < 199901L ) + + // No ANSI C 1999/2000 stdint.h integer width declarations + + #ifdef _MSC_EXTENSIONS + + // Use Microsoft C compiler integer width declarations + + typedef unsigned __int64 uint64_t; + typedef __int64 int64_t; + typedef unsigned __int32 uint32_t; + typedef __int32 int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + #ifdef UNIX_LP64 + + // Use LP64 programming model from C_FLAGS for integer width declarations + + typedef unsigned long uint64_t; + typedef long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #else + + // Assume P64 programming model from C_FLAGS for integer width declarations + + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned char uint8_t; + typedef char int8_t; + #endif + #endif +#endif +#endif /* __FreeBSD__ */ + +// +// Basic EFI types of various widths +// + +#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */ +#define ACPI_USE_SYSTEM_INTTYPES 1 /* Tell ACPI we've defined types */ + +typedef uint64_t UINT64; +typedef int64_t INT64; + +#ifndef _BASETSD_H_ + typedef uint32_t UINT32; + typedef int32_t INT32; +#endif + +typedef uint16_t UINT16; +typedef int16_t INT16; +typedef uint8_t UINT8; +typedef int8_t INT8; + +#endif + +#undef VOID +#define VOID void + + +typedef int64_t INTN; +typedef uint64_t UINTN; + +#ifdef EFI_NT_EMULATOR + #define POST_CODE(_Data) +#else + #ifdef EFI_DEBUG +#define POST_CODE(_Data) __asm mov eax,(_Data) __asm out 0x80,al + #else + #define POST_CODE(_Data) + #endif +#endif + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() __asm { int 3 } + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 4 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifdef __amd64__ +#define EFIAPI __attribute__((ms_abi)) +#endif + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options + #ifdef _MSC_EXTENSIONS + #define EFIAPI __cdecl // Force C calling convention for Microsoft C compiler + #else + #define EFIAPI // Substitute expresion to force C calling convention + #endif +#endif + +#define BOOTSERVICE +//#define RUNTIMESERVICE(proto,a) alloc_text("rtcode",a); proto a +//#define RUNTIMEFUNCTION(proto,a) alloc_text("rtcode",a); proto a +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE() + +#ifdef EFI_NO_INTERFACE_DECL + #define EFI_FORWARD_DECLARATION(x) + #define EFI_INTERFACE_DECL(x) +#else + #define EFI_FORWARD_DECLARATION(x) typedef struct _##x x + #define EFI_INTERFACE_DECL(x) typedef struct x +#endif + +#ifdef EFI_NT_EMULATOR + +// +// To help ensure proper coding of integrated drivers, they are +// compiled as DLLs. In NT they require a dll init entry pointer. +// The macro puts a stub entry point into the DLL so it will load. +// + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + EFI_STATUS \ + InitFunction ( \ + EFI_HANDLE ImageHandle, \ + EFI_SYSTEM_TABLE *SystemTable \ + ); \ + \ + UINTN \ + __stdcall \ + _DllMainCRTStartup ( \ + UINTN Inst, \ + UINTN reason_for_call, \ + VOID *rserved \ + ) \ + { \ + return 1; \ + } \ + \ + int \ + __declspec( dllexport ) \ + __cdecl \ + InitializeDriver ( \ + void *ImageHandle, \ + void *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, SystemTable); \ + } + + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, NULL) + +#else // EFI_NT_EMULATOR + +// +// When building similar to FW, link everything together as +// one big module. +// + + #define EFI_DRIVER_ENTRY_POINT(InitFunction) + + #define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + +#endif // EFI_FW_NT + +#ifdef __FreeBSD__ +#define INTERFACE_DECL(x) struct x +#elif __rtems__ +#define INTERFACE_DECL(x) struct x +#else +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. +// +#ifdef NO_INTERFACE_DECL +#define INTERFACE_DECL(x) +#else +#define INTERFACE_DECL(x) typedef struct x +#endif +#endif /* __FreeBSD__ */ + +#ifdef _MSC_EXTENSIONS +#pragma warning ( disable : 4731 ) // Suppress warnings about modification of EBP +#endif + diff --git a/bsps/shared/freebsd/stand/efi/include/efi.h b/bsps/shared/freebsd/stand/efi/include/efi.h new file mode 100644 index 0000000000..5b4743d44b --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efi.h @@ -0,0 +1,87 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efi.h + +Abstract: + + Public EFI header files + + + +Revision History + +--*/ + +// +// Build flags on input +// EFI32 +// EFI_DEBUG - Enable debugging code +// EFI_NT_EMULATOR - Building for running under NT +// + + +#ifndef _EFI_INCLUDE_ +#define _EFI_INCLUDE_ + +#define EFI_FIRMWARE_VENDOR L"INTEL" +#define EFI_FIRMWARE_MAJOR_REVISION 14 +#define EFI_FIRMWARE_MINOR_REVISION 62 +#define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION)) + +#include "efibind.h" +#include "efidef.h" +#include "efidevp.h" +#ifndef __rtems__ +#include "efipciio.h" +#include "efiprot.h" +#endif /* __rtems__ */ +#include "eficon.h" +#include "eficonsctl.h" +#ifndef __rtems__ +#include "efiser.h" +#include "efi_nii.h" +#include "efipxebc.h" +#include "efinet.h" +#endif /* __rtems__ */ +#include "efiapi.h" +#ifndef __rtems__ +#include "efifs.h" +#endif /* __rtems__ */ +#include "efierr.h" +#include "efigop.h" +#ifndef __rtems__ +#include "efiip.h" +#include "efiudp.h" +#include "efitcp.h" +#include "efipoint.h" +#include "efiuga.h" +#endif /* __rtems__ */ +#include <sys/types.h> +#ifdef __rtems__ +#include <stdbool.h> +#endif +/* + * Global variables + */ +extern EFI_LOADED_IMAGE *boot_img; +extern bool boot_services_active; + +/* + * FreeBSD UUID + */ +#define FREEBSD_BOOT_VAR_GUID \ + { 0xCFEE69AD, 0xA0DE, 0x47A9, {0x93, 0xA8, 0xF6, 0x31, 0x06, 0xF8, 0xAE, 0x99} } + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efiapi.h b/bsps/shared/freebsd/stand/efi/include/efiapi.h new file mode 100644 index 0000000000..fb5c861b38 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efiapi.h @@ -0,0 +1,1204 @@ +/* $FreeBSD$ */ +#ifndef _EFI_API_H +#define _EFI_API_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efiapi.h + +Abstract: + + Global EFI runtime & boot service interfaces + + + + +Revision History + +--*/ + +// +// EFI Specification Revision +// + +#define EFI_SPECIFICATION_MAJOR_REVISION 1 +#define EFI_SPECIFICATION_MINOR_REVISION 10 + +// +// Declare forward referenced data structures +// + +INTERFACE_DECL(_EFI_SYSTEM_TABLE); + +// +// EFI Memory +// + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_PAGES) ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NoPages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_PAGES) ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NoPages + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MEMORY_MAP) ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +#define NextMemoryDescriptor(Ptr,Size) ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) Ptr) + Size)) + + +typedef +EFI_STATUS +(EFIAPI *EFI_ALLOCATE_POOL) ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_FREE_POOL) ( + IN VOID *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP) ( + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize, + IN UINT32 DescriptorVersion, + IN EFI_MEMORY_DESCRIPTOR *VirtualMap + ); + + +#define EFI_OPTIONAL_PTR 0x00000001 +#define EFI_INTERNAL_FNC 0x00000002 // Pointer to internal runtime fnc +#define EFI_INTERNAL_PTR 0x00000004 // Pointer to internal runtime data + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONVERT_POINTER) ( + IN UINTN DebugDisposition, + IN OUT VOID **Address + ); + + +// +// EFI Events +// + + + +#define EVT_TIMER 0x80000000 +#define EVT_RUNTIME 0x40000000 +#define EVT_RUNTIME_CONTEXT 0x20000000 + +#define EVT_NOTIFY_WAIT 0x00000100 +#define EVT_NOTIFY_SIGNAL 0x00000200 + +#define EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#define EVT_EFI_SIGNAL_MASK 0x000000FF +#define EVT_EFI_SIGNAL_MAX 2 + +typedef +VOID +(EFIAPI *EFI_EVENT_NOTIFY) ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CREATE_EVENT) ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *Event + ); + +typedef enum { + TimerCancel, + TimerPeriodic, + TimerRelative, + TimerTypeMax +} EFI_TIMER_DELAY; + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIMER) ( + IN EFI_EVENT Event, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SIGNAL_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_WAIT_FOR_EVENT) ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *Event, + OUT UINTN *Index + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLOSE_EVENT) ( + IN EFI_EVENT Event + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CHECK_EVENT) ( + IN EFI_EVENT Event + ); + +// +// Task priority level +// + +#define TPL_APPLICATION 4 +#define TPL_CALLBACK 8 +#define TPL_NOTIFY 16 +#define TPL_HIGH_LEVEL 31 + +typedef +EFI_TPL +(EFIAPI *EFI_RAISE_TPL) ( + IN EFI_TPL NewTpl + ); + +typedef +VOID +(EFIAPI *EFI_RESTORE_TPL) ( + IN EFI_TPL OldTpl + ); + + +// +// EFI platform varibles +// + +#define EFI_GLOBAL_VARIABLE \ + { 0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C} } + +// Variable attributes +#define EFI_VARIABLE_NON_VOLATILE 0x00000001 +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002 +#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004 +#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008 +#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 +#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 +#define EFI_VARIABLE_APPEND_WRITE 0x00000040 + +// Variable size limitation +#define EFI_MAXIMUM_VARIABLE_SIZE 1024 + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_VARIABLE) ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes OPTIONAL, + IN OUT UINTN *DataSize, + OUT VOID *Data + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_VARIABLE_NAME) ( + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VendorGuid + ); + + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_VARIABLE) ( + IN const CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + + +// +// EFI Time +// + +typedef struct { + UINT32 Resolution; // 1e-6 parts per million + UINT32 Accuracy; // hertz + BOOLEAN SetsToZero; // Set clears sub-second time +} EFI_TIME_CAPABILITIES; + + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_TIME) ( + OUT EFI_TIME *Time, + OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_TIME) ( + IN EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_WAKEUP_TIME) ( + OUT BOOLEAN *Enabled, + OUT BOOLEAN *Pending, + OUT EFI_TIME *Time + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WAKEUP_TIME) ( + IN BOOLEAN Enable, + IN EFI_TIME *Time OPTIONAL + ); + + +// +// Image functions +// + + +// PE32+ Subsystem type for EFI images + +#if !defined(IMAGE_SUBSYSTEM_EFI_APPLICATION) +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#endif + +// PE32+ Machine type for EFI images + +#if !defined(EFI_IMAGE_MACHINE_IA32) +#define EFI_IMAGE_MACHINE_IA32 0x014c +#endif + +#if !defined(EFI_IMAGE_MACHINE_EBC) +#define EFI_IMAGE_MACHINE_EBC 0x0EBC +#endif + +// Image Entry prototype + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_ENTRY_POINT) ( + IN EFI_HANDLE ImageHandle, + IN struct _EFI_SYSTEM_TABLE *SystemTable + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_LOAD) ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_START) ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT) ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS ExitStatus, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ) +#ifndef __rtems__ + __dead2 +#endif + ; + +typedef +EFI_STATUS +(EFIAPI *EFI_IMAGE_UNLOAD) ( + IN EFI_HANDLE ImageHandle + ); + + +// Image handle +#define LOADED_IMAGE_PROTOCOL \ + { 0x5B1B31A1, 0x9562, 0x11d2, {0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B} } + +#define EFI_LOADED_IMAGE_INFORMATION_REVISION 0x1000 +typedef struct { + UINT32 Revision; + EFI_HANDLE ParentHandle; + struct _EFI_SYSTEM_TABLE *SystemTable; + + // Source location of image + EFI_HANDLE DeviceHandle; + EFI_DEVICE_PATH *FilePath; + VOID *Reserved; + + // Images load options + UINT32 LoadOptionsSize; + VOID *LoadOptions; + + // Location of where image was loaded + VOID *ImageBase; + UINT64 ImageSize; + EFI_MEMORY_TYPE ImageCodeType; + EFI_MEMORY_TYPE ImageDataType; + + // If the driver image supports a dynamic unload request + EFI_IMAGE_UNLOAD Unload; + +} EFI_LOADED_IMAGE; + + +typedef +EFI_STATUS +(EFIAPI *EFI_EXIT_BOOT_SERVICES) ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +// +// Misc +// + + +typedef +EFI_STATUS +(EFIAPI *EFI_STALL) ( + IN UINTN Microseconds + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_WATCHDOG_TIMER) ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + + +typedef enum { + EfiResetCold, + EfiResetWarm, + EfiResetShutdown +} EFI_RESET_TYPE; + +typedef +VOID +(EFIAPI *EFI_RESET_SYSTEM) ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN CHAR16 *ResetData OPTIONAL + ) +#ifndef __rtems__ + __dead2 +#endif + ; + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_MONOTONIC_COUNT) ( + OUT UINT64 *Count + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_NEXT_HIGH_MONO_COUNT) ( + OUT UINT32 *HighCount + ); + +// +// Protocol handler functions +// + +typedef enum { + EFI_NATIVE_INTERFACE +} EFI_INTERFACE_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_PROTOCOL_INTERFACE) ( + IN OUT EFI_HANDLE *Handle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNINSTALL_PROTOCOL_INTERFACE) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_HANDLE_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_PROTOCOL_NOTIFY) ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +typedef enum { + AllHandles, + ByRegisterNotify, + ByProtocol +} EFI_LOCATE_SEARCH_TYPE; + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_HANDLE) ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_DEVICE_PATH) ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH **DevicePath, + OUT EFI_HANDLE *Device + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_CONFIGURATION_TABLE) ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_RESERVED_SERVICE) ( + VOID + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CONNECT_CONTROLLER) ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_DISCONNECT_CONTROLLER)( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle, OPTIONAL + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 +#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 +#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 +#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020 + +typedef +EFI_STATUS +(EFIAPI *EFI_OPEN_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE ControllerHandle, OPTIONAL + IN UINT32 Attributes + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLOSE_PROTOCOL) ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE DeviceHandle + ); + +typedef struct { + EFI_HANDLE AgentHandle; + EFI_HANDLE ControllerHandle; + UINT32 Attributes; + UINT32 OpenCount; +} EFI_OPEN_PROTOCOL_INFORMATION_ENTRY; + +typedef +EFI_STATUS +(EFIAPI *EFI_OPEN_PROTOCOL_INFORMATION) ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_PROTOCOLS_PER_HANDLE) ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_HANDLE_BUFFER) ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_LOCATE_PROTOCOL) ( + EFI_GUID *Protocol, + VOID *Registration, OPTIONAL + VOID **Interface + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) ( + IN EFI_HANDLE Handle, + ... + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CALCULATE_CRC32) ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ); + +typedef +VOID +(EFIAPI *EFI_COPY_MEM) ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ); + +typedef +VOID +(EFIAPI *EFI_SET_MEM) ( + IN VOID *Buffer, + IN UINTN Size, + IN UINT8 Value + ); + +// +// Standard EFI table header +// + +typedef struct _EFI_TABLE_HEARDER { + UINT64 Signature; + UINT32 Revision; + UINT32 HeaderSize; + UINT32 CRC32; + UINT32 Reserved; +} EFI_TABLE_HEADER; + + +// +// EFI Runtime Serivces Table +// + +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 +#define EFI_RUNTIME_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION)) + +typedef struct { + EFI_TABLE_HEADER Hdr; + + // + // Time services + // + + EFI_GET_TIME GetTime; + EFI_SET_TIME SetTime; + EFI_GET_WAKEUP_TIME GetWakeupTime; + EFI_SET_WAKEUP_TIME SetWakeupTime; + + // + // Virtual memory services + // + + EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap; + EFI_CONVERT_POINTER ConvertPointer; + + // + // Variable serviers + // + + EFI_GET_VARIABLE GetVariable; + EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName; + EFI_SET_VARIABLE SetVariable; + + // + // Misc + // + + EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount; + EFI_RESET_SYSTEM ResetSystem; + +} EFI_RUNTIME_SERVICES; + + +// +// EFI Boot Services Table +// + +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 +#define EFI_BOOT_SERVICES_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION)) + +typedef struct { + + EFI_TABLE_HEADER Hdr; + + // + // Task priority functions + // + + EFI_RAISE_TPL RaiseTPL; + EFI_RESTORE_TPL RestoreTPL; + + // + // Memory functions + // + + EFI_ALLOCATE_PAGES AllocatePages; + EFI_FREE_PAGES FreePages; + EFI_GET_MEMORY_MAP GetMemoryMap; + EFI_ALLOCATE_POOL AllocatePool; + EFI_FREE_POOL FreePool; + + // + // Event & timer functions + // + + EFI_CREATE_EVENT CreateEvent; + EFI_SET_TIMER SetTimer; + EFI_WAIT_FOR_EVENT WaitForEvent; + EFI_SIGNAL_EVENT SignalEvent; + EFI_CLOSE_EVENT CloseEvent; + EFI_CHECK_EVENT CheckEvent; + + // + // Protocol handler functions + // + + EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface; + EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface; + EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface; + EFI_HANDLE_PROTOCOL HandleProtocol; + VOID *Reserved; + EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify; + EFI_LOCATE_HANDLE LocateHandle; + EFI_LOCATE_DEVICE_PATH LocateDevicePath; + EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable; + + // + // Image functions + // + + EFI_IMAGE_LOAD LoadImage; + EFI_IMAGE_START StartImage; + EFI_EXIT Exit; + EFI_IMAGE_UNLOAD UnloadImage; + EFI_EXIT_BOOT_SERVICES ExitBootServices; + + // + // Misc functions + // + + EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount; + EFI_STALL Stall; + EFI_SET_WATCHDOG_TIMER SetWatchdogTimer; + + // + // DriverSupport Services + // + EFI_CONNECT_CONTROLLER ConnectController; + EFI_DISCONNECT_CONTROLLER DisconnectController; + + // + // Open and Close Protocol Services + // + EFI_OPEN_PROTOCOL OpenProtocol; + EFI_CLOSE_PROTOCOL CloseProtocol; + EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation; + + // + // Library Services to reduce size of drivers + // + EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle; + EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer; + EFI_LOCATE_PROTOCOL LocateProtocol; + + EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces; + EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces; + + // + // CRC32 services + // + EFI_CALCULATE_CRC32 CalculateCrc32; + + // + // Memory Utility Services + // + EFI_COPY_MEM CopyMem; + EFI_SET_MEM SetMem; + +} EFI_BOOT_SERVICES; + + +// +// EFI Configuration Table and GUID definitions +// + +#define MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define ACPI_TABLE_GUID \ + { 0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define ACPI_20_TABLE_GUID \ + { 0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } + +#define SMBIOS_TABLE_GUID \ + { 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define SMBIOS3_TABLE_GUID \ + { 0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94} } + +#define SAL_SYSTEM_TABLE_GUID \ + { 0xeb9d2d32, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define FDT_TABLE_GUID \ + { 0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0} } + +#define DXE_SERVICES_TABLE_GUID \ + { 0x5ad34ba, 0x6f02, 0x4214, {0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9} } + +#define HOB_LIST_TABLE_GUID \ + { 0x7739f24c, 0x93d7, 0x11d4, {0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define LZMA_DECOMPRESSION_GUID \ + { 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x3, 0xcf} } + +#define ARM_MP_CORE_INFO_TABLE_GUID \ + { 0xa4ee0728, 0xe5d7, 0x4ac5, {0xb2, 0x1e, 0x65, 0x8e, 0xd8, 0x57, 0xe8, 0x34} } + +#define ESRT_TABLE_GUID \ + { 0xb122a263, 0x3661, 0x4f68, {0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80} } + +#define MEMORY_TYPE_INFORMATION_TABLE_GUID \ + { 0x4c19049f, 0x4137, 0x4dd3, {0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa} } + +#define DEBUG_IMAGE_INFO_TABLE_GUID \ + { 0x49152e77, 0x1ada, 0x4764, {0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b} } + +typedef struct _EFI_CONFIGURATION_TABLE { + EFI_GUID VendorGuid; + VOID *VendorTable; +} EFI_CONFIGURATION_TABLE; + + +// +// EFI System Table +// + + + + +#define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 +#define EFI_SYSTEM_TABLE_REVISION ((EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION)) +#define EFI_1_10_SYSTEM_TABLE_REVISION ((1<<16) | 10) +#define EFI_1_02_SYSTEM_TABLE_REVISION ((1<<16) | 02) + +typedef struct _EFI_SYSTEM_TABLE { + EFI_TABLE_HEADER Hdr; + + CHAR16 *FirmwareVendor; + UINT32 FirmwareRevision; + + EFI_HANDLE ConsoleInHandle; + SIMPLE_INPUT_INTERFACE *ConIn; + + EFI_HANDLE ConsoleOutHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *ConOut; + + EFI_HANDLE StandardErrorHandle; + SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr; + + EFI_RUNTIME_SERVICES *RuntimeServices; + EFI_BOOT_SERVICES *BootServices; + + UINTN NumberOfTableEntries; + EFI_CONFIGURATION_TABLE *ConfigurationTable; + +} EFI_SYSTEM_TABLE; + +/* + * unlisted GUID's.. + */ +#define EFI_EBC_INTERPRETER_PROTOCOL_GUID \ +{ 0x13AC6DD1, 0x73D0, 0x11D4, {0xB0, 0x6B, 0x00, 0xAA, 0x00, 0xBD, 0x6D, 0xE7} } + +#define EFI_DRIVER_CONFIGURATION2_PROTOCOL_GUID \ +{ 0xbfd7dc1d, 0x24f1, 0x40d9, {0x82, 0xe7, 0x2e, 0x09, 0xbb, 0x6b, 0x4e, 0xbe} } + +#define EFI_DRIVER_CONFIGURATION_PROTOCOL_GUID \ +{ 0x107a772b, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_DRIVER_BINDING_PROTOCOL_GUID \ + { 0x18A031AB, 0xB443, 0x4D1A, \ + { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \ + } + +#define EFI_TAPE_IO_PROTOCOL_GUID \ + { 0x1e93e633, 0xd65a, 0x459e, \ + { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \ + } + +#define EFI_SCSI_IO_PROTOCOL_GUID \ + { 0x932f47e6, 0x2362, 0x4002, \ + { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ + } + +#define EFI_USB2_HC_PROTOCOL_GUID \ + { 0x3e745226, 0x9818, 0x45b6, \ + { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \ + } + +#define EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ + { 0x2755590C, 0x6F3C, 0x42FA, \ + { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \ + } + +#define EFI_DEBUGPORT_PROTOCOL_GUID \ + { 0xEBA4E8D2, 0x3858, 0x41EC, \ + { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ + } + +#define EFI_DECOMPRESS_PROTOCOL_GUID \ + { 0xd8117cfe, 0x94a6, 0x11d4, \ + { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define EFI_ACPI_TABLE_PROTOCOL_GUID \ + { 0xffe06bdd, 0x6107, 0x46a6, \ + { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \ + } + +#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ + { 0x587e72d7, 0xcc50, 0x4f79, \ + { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \ + } + +#define EFI_HII_DATABASE_PROTOCOL_GUID \ + { 0xef9fc172, 0xa1b2, 0x4693, \ + { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \ + } + +#define EFI_HII_STRING_PROTOCOL_GUID \ + { 0xfd96974, 0x23aa, 0x4cdc, \ + { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \ + } + +#define EFI_HII_IMAGE_PROTOCOL_GUID \ + { 0x31a6406a, 0x6bdf, 0x4e46, \ + { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \ + } + +#define EFI_HII_FONT_PROTOCOL_GUID \ + { 0xe9ca4775, 0x8657, 0x47fc, \ + { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \ + } +#define EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \ + { 0x330d4706, 0xf2a0, 0x4e4f, \ + { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \ + } + +#define EFI_COMPONENT_NAME_PROTOCOL_GUID \ +{ 0x107a772c, 0xd5e1, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_COMPONENT_NAME2_PROTOCOL_GUID \ + { 0x6a7a5cff, 0xe8d9, 0x4f70, \ + { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \ + } + +#define EFI_USB_IO_PROTOCOL_GUID \ + { 0x2B2F68D6, 0x0CD2, 0x44cf, \ + { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \ + } +#define EFI_HCDP_TABLE_GUID \ + { 0xf951938d, 0x620b, 0x42ef, \ + { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \ + } + +#define EFI_DEVICE_TREE_GUID \ + { 0xb1b621d5, 0xf19c, 0x41a5, \ + { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \ + } + +#define EFI_VENDOR_APPLE_GUID \ + { 0x2B0585EB, 0xD8B8, 0x49A9, \ + { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \ + } + +#define EFI_CONSOLE_IN_DEVICE_GUID \ +{ 0xd3b36f2b, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_CONSOLE_OUT_DEVICE_GUID \ +{ 0xd3b36f2c, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_STANDARD_ERROR_DEVICE_GUID \ +{ 0xd3b36f2d, 0xd551, 0x11d4, {0x9a, 0x46, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_UNICODE_COLLATION2_PROTOCOL_GUID \ +{ 0xa4c751fc, 0x23ae, 0x4c3e, {0x92, 0xe9, 0x49, 0x64, 0xcf, 0x63, 0xf3, 0x49} } + +#define EFI_FORM_BROWSER2_PROTOCOL_GUID \ +{ 0xb9d4c360, 0xbcfb, 0x4f9b, {0x92, 0x98, 0x53, 0xc1, 0x36, 0x98, 0x22, 0x58} } + +#define EFI_ARP_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0xf44c00ee, 0x1f2c, 0x4a00, {0xaa, 0x9, 0x1c, 0x9f, 0x3e, 0x8, 0x0, 0xa3} } + +#define EFI_ARP_PROTOCOL_GUID \ +{ 0xf4b427bb, 0xba21, 0x4f16, {0xbc, 0x4e, 0x43, 0xe4, 0x16, 0xab, 0x61, 0x9c} } + +#define EFI_IP4_CONFIG_PROTOCOL_GUID \ +{ 0x3b95aa31, 0x3793, 0x434b, {0x86, 0x67, 0xc8, 0x07, 0x08, 0x92, 0xe0, 0x5e} } + +#define EFI_IP6_CONFIG_PROTOCOL_GUID \ +{ 0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a} } + +#define EFI_MANAGED_NETWORK_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0xf36ff770, 0xa7e1, 0x42cf, {0x9e, 0xd2, 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c} } + +#define EFI_MANAGED_NETWORK_PROTOCOL_GUID \ +{ 0x7ab33a91, 0xace5, 0x4326, {0xb5, 0x72, 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16} } + +#define EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0x2FE800BE, 0x8F01, 0x4aa6, {0x94, 0x6B, 0xD7, 0x13, 0x88, 0xE1, 0x83, 0x3F} } + +#define EFI_MTFTP4_PROTOCOL_GUID \ +{ 0x78247c57, 0x63db, 0x4708, {0x99, 0xc2, 0xa8, 0xb4, 0xa9, 0xa6, 0x1f, 0x6b} } + +#define EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0xd9760ff3, 0x3cca, 0x4267, {0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23} } + +#define EFI_MTFTP6_PROTOCOL_GUID \ +{ 0xbf0a78ba, 0xec29, 0x49cf, {0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51} } + +#define EFI_DHCP4_PROTOCOL_GUID \ +{ 0x8a219718, 0x4ef5, 0x4761, {0x91, 0xc8, 0xc0, 0xf0, 0x4b, 0xda, 0x9e, 0x56} } + +#define EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0x9d9a39d8, 0xbd42, 0x4a73, {0xa4, 0xd5, 0x8e, 0xe9, 0x4b, 0xe1, 0x13, 0x80} } + +#define EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID \ +{ 0x9fb9a8a1, 0x2f4a, 0x43a6, {0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5} } + +#define EFI_DHCP6_PROTOCOL_GUID \ +{ 0x87c8bad7, 0x595, 0x4053, {0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b} } + +#define EFI_SCSI_PASS_THRU_PROTOCOL_GUID \ +{ 0xa59e8fcf, 0xbda0, 0x43bb, {0x90, 0xb1, 0xd3, 0x73, 0x2e, 0xca, 0xa8, 0x77} } + +#define EFI_EXT_SCSI_PASS_THRU_PROTOCOL_GUID \ +{ 0x143b7632, 0xb81b, 0x4cb7, {0xab, 0xd3, 0xb6, 0x25, 0xa5, 0xb9, 0xbf, 0xfe} } + +#define EFI_DISK_INFO_PROTOCOL_GUID \ +{ 0xd432a67f, 0x14dc, 0x484b, {0xb3, 0xbb, 0x3f, 0x2, 0x91, 0x84, 0x93, 0x27} } + +#define EFI_ISA_IO_PROTOCOL_GUID \ +{ 0x7ee2bd44, 0x3da0, 0x11d4, { 0x9a, 0x38, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_VLAN_CONFIG_PROTOCOL_GUID \ +{ 0x9e23d768, 0xd2f3, 0x4366, {0x9f, 0xc3, 0x3a, 0x7a, 0xba, 0x86, 0x43, 0x74} } + +#define EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID \ +{ 0xa1e37052, 0x80d9, 0x4e65, {0xa3, 0x17, 0x3e, 0x9a, 0x55, 0xc4, 0x3e, 0xc9} } + +#define EFI_ISA_ACPI_PROTOCOL_GUID \ +{ 0x64a892dc, 0x5561, 0x4536, {0x92, 0xc7, 0x79, 0x9b, 0xfc, 0x18, 0x33, 0x55} } + +#define EFI_PCI_ENUMERATION_COMPLETE_GUID \ +{ 0x30cfe3e7, 0x3de1, 0x4586, {0xbe, 0x20, 0xde, 0xab, 0xa1, 0xb3, 0xb7, 0x93} } + +#define EFI_DRIVER_DIAGNOSTICS_PROTOCOL_GUID \ +{ 0x0784924f, 0xe296, 0x11d4, {0x9a, 0x49, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } } + +#define EFI_DRIVER_DIAGNOSTICS2_PROTOCOL_GUID \ +{ 0x4d330321, 0x025f, 0x4aac, {0x90, 0xd8, 0x5e, 0xd9, 0x00, 0x17, 0x3b, 0x63} } + +#define EFI_CAPSULE_ARCH_PROTOCOL_GUID \ +{ 0x5053697e, 0x2cbc, 0x4819, {0x90, 0xd9, 0x05, 0x80, 0xde, 0xee, 0x57, 0x54} } + +#define EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID \ +{0x1da97072, 0xbddc, 0x4b30, {0x99, 0xf1, 0x72, 0xa0, 0xb5, 0x6f, 0xff, 0x2a} } + +#define EFI_REALTIME_CLOCK_ARCH_PROTOCOL_GUID \ +{0x27cfac87, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_MP_SERVICES_PROTOCOL_GUID \ +{ 0x3fdda605, 0xa76e, 0x4f46, {0xad, 0x29, 0x12, 0xf4, 0x53, 0x1b, 0x3d, 0x08} } + +#define EFI_VARIABLE_ARCH_PROTOCOL_GUID \ +{ 0x1e5668e2, 0x8481, 0x11d4, {0xbc, 0xf1, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID \ +{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} } + +#define EFI_WATCHDOG_TIMER_ARCH_PROTOCOL_GUID \ +{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} } + +#define EFI_ACPI_SUPPORT_PROTOCOL_GUID \ +{ 0x6441f818, 0x6362, 0x4e44, {0xb5, 0x70, 0x7d, 0xba, 0x31, 0xdd, 0x24, 0x53} } + +#define EFI_BDS_ARCH_PROTOCOL_GUID \ +{ 0x665e3ff6, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_METRONOME_ARCH_PROTOCOL_GUID \ +{ 0x26baccb2, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define EFI_TIMER_ARCH_PROTOCOL_GUID \ +{ 0x26baccb3, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define EFI_DPC_PROTOCOL_GUID \ +{ 0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6} } + +#define EFI_PRINT2_PROTOCOL_GUID \ +{ 0xf05976ef, 0x83f1, 0x4f3d, {0x86, 0x19, 0xf7, 0x59, 0x5d, 0x41, 0xe5, 0x38} } + +#define EFI_RESET_ARCH_PROTOCOL_GUID \ +{ 0x27cfac88, 0x46cc, 0x11d4, {0x9a, 0x38, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define EFI_CPU_ARCH_PROTOCOL_GUID \ +{ 0x26baccb1, 0x6f42, 0x11d4, {0xbc, 0xe7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } } + +#define EFI_CPU_IO2_PROTOCOL_GUID \ +{ 0xad61f191, 0xae5f, 0x4c0e, {0xb9, 0xfa, 0xe8, 0x69, 0xd2, 0x88, 0xc6, 0x4f} } + +#define EFI_LEGACY_8259_PROTOCOL_GUID \ +{ 0x38321dba, 0x4fe0, 0x4e17, {0x8a, 0xec, 0x41, 0x30, 0x55, 0xea, 0xed, 0xc1} } + +#define EFI_SECURITY_ARCH_PROTOCOL_GUID \ +{ 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39} } + +#define EFI_SECURITY2_ARCH_PROTOCOL_GUID \ +{ 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68} } + +#define EFI_RUNTIME_ARCH_PROTOCOL_GUID \ +{ 0xb7dfb4e1, 0x52f, 0x449f, {0x87, 0xbe, 0x98, 0x18, 0xfc, 0x91, 0xb7, 0x33} } + +#define EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID \ +{ 0xd2b2b828, 0x826, 0x48a7, {0xb3, 0xdf, 0x98, 0x3c, 0x0, 0x60, 0x24, 0xf0} } + +#define EFI_DATA_HUB_PROTOCOL_GUID \ +{ 0xae80d021, 0x618e, 0x11d4, {0xbc, 0xd7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81} } + +#define PCD_PROTOCOL_GUID \ +{ 0x11b34006, 0xd85b, 0x4d0a, { 0xa2, 0x90, 0xd5, 0xa5, 0x71, 0x31, 0xe, 0xf7} } + +#define EFI_PCD_PROTOCOL_GUID \ +{ 0x13a3f0f6, 0x264a, 0x3ef0, {0xf2, 0xe0, 0xde, 0xc5, 0x12, 0x34, 0x2f, 0x34} } + +#define EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID \ +{ 0x8f644fa9, 0xe850, 0x4db1, {0x9c, 0xe2, 0xb, 0x44, 0x69, 0x8e, 0x8d, 0xa4 } } + +#define EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID \ +{ 0x220e73b6, 0x6bdb, 0x4413, { 0x84, 0x5, 0xb9, 0x74, 0xb1, 0x8, 0x61, 0x9a } } + +#define EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID \ +{ 0x7aa35a69, 0x506c, 0x444f, {0xa7, 0xaf, 0x69, 0x4b, 0xf5, 0x6f, 0x71, 0xc8} } + +#define LZMA_COMPRESS_GUID \ +{ 0xee4e5898, 0x3914, 0x4259, {0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf} } +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/eficon.h b/bsps/shared/freebsd/stand/efi/include/eficon.h new file mode 100644 index 0000000000..ba80114eb9 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/eficon.h @@ -0,0 +1,527 @@ +/* $FreeBSD$ */ +#ifndef _EFI_CON_H +#define _EFI_CON_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + eficon.h + +Abstract: + + EFI console protocols + + + +Revision History + +--*/ + +// +// Text output protocol +// + +#define SIMPLE_TEXT_OUTPUT_PROTOCOL \ + { 0x387477c2, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +INTERFACE_DECL(_SIMPLE_TEXT_OUTPUT_INTERFACE); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_RESET) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_OUTPUT_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_TEST_STRING) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN CHAR16 *String + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_QUERY_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber, + OUT UINTN *Columns, + OUT UINTN *Rows + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_MODE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN ModeNumber + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_ATTRIBUTE) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Attribute + ); + +#define EFI_BLACK 0x00 +#define EFI_BLUE 0x01 +#define EFI_GREEN 0x02 +#define EFI_CYAN (EFI_BLUE | EFI_GREEN) +#define EFI_RED 0x04 +#define EFI_MAGENTA (EFI_BLUE | EFI_RED) +#define EFI_BROWN (EFI_GREEN | EFI_RED) +#define EFI_LIGHTGRAY (EFI_BLUE | EFI_GREEN | EFI_RED) +#define EFI_BRIGHT 0x08 +#define EFI_DARKGRAY (EFI_BRIGHT) +#define EFI_LIGHTBLUE (EFI_BLUE | EFI_BRIGHT) +#define EFI_LIGHTGREEN (EFI_GREEN | EFI_BRIGHT) +#define EFI_LIGHTCYAN (EFI_CYAN | EFI_BRIGHT) +#define EFI_LIGHTRED (EFI_RED | EFI_BRIGHT) +#define EFI_LIGHTMAGENTA (EFI_MAGENTA | EFI_BRIGHT) +#define EFI_YELLOW (EFI_BROWN | EFI_BRIGHT) +#define EFI_WHITE (EFI_BLUE | EFI_GREEN | EFI_RED | EFI_BRIGHT) + +#define EFI_TEXT_ATTR(f,b) ((f) | ((b) << 4)) + +#define EFI_BACKGROUND_BLACK 0x00 +#define EFI_BACKGROUND_BLUE 0x10 +#define EFI_BACKGROUND_GREEN 0x20 +#define EFI_BACKGROUND_CYAN (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN) +#define EFI_BACKGROUND_RED 0x40 +#define EFI_BACKGROUND_MAGENTA (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_BROWN (EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) +#define EFI_BACKGROUND_LIGHTGRAY (EFI_BACKGROUND_BLUE | EFI_BACKGROUND_GREEN | EFI_BACKGROUND_RED) + + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_CLEAR_SCREEN) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_SET_CURSOR_POSITION) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN UINTN Column, + IN UINTN Row + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_TEXT_ENABLE_CURSOR) ( + IN struct _SIMPLE_TEXT_OUTPUT_INTERFACE *This, + IN BOOLEAN Enable + ); + +typedef struct { + INT32 MaxMode; + // current settings + INT32 Mode; + INT32 Attribute; + INT32 CursorColumn; + INT32 CursorRow; + BOOLEAN CursorVisible; +} SIMPLE_TEXT_OUTPUT_MODE; + +typedef struct _SIMPLE_TEXT_OUTPUT_INTERFACE { + EFI_TEXT_RESET Reset; + + EFI_TEXT_OUTPUT_STRING OutputString; + EFI_TEXT_TEST_STRING TestString; + + EFI_TEXT_QUERY_MODE QueryMode; + EFI_TEXT_SET_MODE SetMode; + EFI_TEXT_SET_ATTRIBUTE SetAttribute; + + EFI_TEXT_CLEAR_SCREEN ClearScreen; + EFI_TEXT_SET_CURSOR_POSITION SetCursorPosition; + EFI_TEXT_ENABLE_CURSOR EnableCursor; + + // Current mode + SIMPLE_TEXT_OUTPUT_MODE *Mode; +} SIMPLE_TEXT_OUTPUT_INTERFACE; + +// +// Define's for required EFI Unicode Box Draw character +// + +#define BOXDRAW_HORIZONTAL 0x2500 +#define BOXDRAW_VERTICAL 0x2502 +#define BOXDRAW_DOWN_RIGHT 0x250c +#define BOXDRAW_DOWN_LEFT 0x2510 +#define BOXDRAW_UP_RIGHT 0x2514 +#define BOXDRAW_UP_LEFT 0x2518 +#define BOXDRAW_VERTICAL_RIGHT 0x251c +#define BOXDRAW_VERTICAL_LEFT 0x2524 +#define BOXDRAW_DOWN_HORIZONTAL 0x252c +#define BOXDRAW_UP_HORIZONTAL 0x2534 +#define BOXDRAW_VERTICAL_HORIZONTAL 0x253c + +#define BOXDRAW_DOUBLE_HORIZONTAL 0x2550 +#define BOXDRAW_DOUBLE_VERTICAL 0x2551 +#define BOXDRAW_DOWN_RIGHT_DOUBLE 0x2552 +#define BOXDRAW_DOWN_DOUBLE_RIGHT 0x2553 +#define BOXDRAW_DOUBLE_DOWN_RIGHT 0x2554 + +#define BOXDRAW_DOWN_LEFT_DOUBLE 0x2555 +#define BOXDRAW_DOWN_DOUBLE_LEFT 0x2556 +#define BOXDRAW_DOUBLE_DOWN_LEFT 0x2557 + +#define BOXDRAW_UP_RIGHT_DOUBLE 0x2558 +#define BOXDRAW_UP_DOUBLE_RIGHT 0x2559 +#define BOXDRAW_DOUBLE_UP_RIGHT 0x255a + +#define BOXDRAW_UP_LEFT_DOUBLE 0x255b +#define BOXDRAW_UP_DOUBLE_LEFT 0x255c +#define BOXDRAW_DOUBLE_UP_LEFT 0x255d + +#define BOXDRAW_VERTICAL_RIGHT_DOUBLE 0x255e +#define BOXDRAW_VERTICAL_DOUBLE_RIGHT 0x255f +#define BOXDRAW_DOUBLE_VERTICAL_RIGHT 0x2560 + +#define BOXDRAW_VERTICAL_LEFT_DOUBLE 0x2561 +#define BOXDRAW_VERTICAL_DOUBLE_LEFT 0x2562 +#define BOXDRAW_DOUBLE_VERTICAL_LEFT 0x2563 + +#define BOXDRAW_DOWN_HORIZONTAL_DOUBLE 0x2564 +#define BOXDRAW_DOWN_DOUBLE_HORIZONTAL 0x2565 +#define BOXDRAW_DOUBLE_DOWN_HORIZONTAL 0x2566 + +#define BOXDRAW_UP_HORIZONTAL_DOUBLE 0x2567 +#define BOXDRAW_UP_DOUBLE_HORIZONTAL 0x2568 +#define BOXDRAW_DOUBLE_UP_HORIZONTAL 0x2569 + +#define BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE 0x256a +#define BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL 0x256b +#define BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL 0x256c + +// +// EFI Required Block Elements Code Chart +// + +#define BLOCKELEMENT_FULL_BLOCK 0x2588 +#define BLOCKELEMENT_LIGHT_SHADE 0x2591 +// +// EFI Required Geometric Shapes Code Chart +// + +#define GEOMETRICSHAPE_UP_TRIANGLE 0x25b2 +#define GEOMETRICSHAPE_RIGHT_TRIANGLE 0x25ba +#define GEOMETRICSHAPE_DOWN_TRIANGLE 0x25bc +#define GEOMETRICSHAPE_LEFT_TRIANGLE 0x25c4 + +// +// EFI Required Arrow shapes +// + +#define ARROW_UP 0x2191 +#define ARROW_DOWN 0x2193 + +// +// Text input protocol +// + +#define SIMPLE_TEXT_INPUT_PROTOCOL \ + { 0x387477c1, 0x69c7, 0x11d2, {0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b} } + +INTERFACE_DECL(_SIMPLE_INPUT_INTERFACE); + +typedef struct { + UINT16 ScanCode; + CHAR16 UnicodeChar; +} EFI_INPUT_KEY; + +// +// Baseline unicode control chars +// + +#define CHAR_NULL 0x0000 +#define CHAR_BACKSPACE 0x0008 +#define CHAR_TAB 0x0009 +#define CHAR_LINEFEED 0x000A +#define CHAR_CARRIAGE_RETURN 0x000D + +// +// Scan codes for base line keys +// + +#define SCAN_NULL 0x0000 +#define SCAN_UP 0x0001 +#define SCAN_DOWN 0x0002 +#define SCAN_RIGHT 0x0003 +#define SCAN_LEFT 0x0004 +#define SCAN_HOME 0x0005 +#define SCAN_END 0x0006 +#define SCAN_INSERT 0x0007 +#define SCAN_DELETE 0x0008 +#define SCAN_PAGE_UP 0x0009 +#define SCAN_PAGE_DOWN 0x000A +#define SCAN_F1 0x000B +#define SCAN_F2 0x000C +#define SCAN_F3 0x000D +#define SCAN_F4 0x000E +#define SCAN_F5 0x000F +#define SCAN_F6 0x0010 +#define SCAN_F7 0x0011 +#define SCAN_F8 0x0012 +#define SCAN_F9 0x0013 +#define SCAN_F10 0x0014 +#define SCAN_ESC 0x0017 + +// +// EFI Scan code Ex +// +#define SCAN_F11 0x0015 +#define SCAN_F12 0x0016 +#define SCAN_F13 0x0068 +#define SCAN_F14 0x0069 +#define SCAN_F15 0x006A +#define SCAN_F16 0x006B +#define SCAN_F17 0x006C +#define SCAN_F18 0x006D +#define SCAN_F19 0x006E +#define SCAN_F20 0x006F +#define SCAN_F21 0x0070 +#define SCAN_F22 0x0071 +#define SCAN_F23 0x0072 +#define SCAN_F24 0x0073 +#define SCAN_MUTE 0x007F +#define SCAN_VOLUME_UP 0x0080 +#define SCAN_VOLUME_DOWN 0x0081 +#define SCAN_BRIGHTNESS_UP 0x0100 +#define SCAN_BRIGHTNESS_DOWN 0x0101 +#define SCAN_SUSPEND 0x0102 +#define SCAN_HIBERNATE 0x0103 +#define SCAN_TOGGLE_DISPLAY 0x0104 +#define SCAN_RECOVERY 0x0105 +#define SCAN_EJECT 0x0106 + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_RESET) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + IN BOOLEAN ExtendedVerification + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_READ_KEY) ( + IN struct _SIMPLE_INPUT_INTERFACE *This, + OUT EFI_INPUT_KEY *Key + ); + +typedef struct _SIMPLE_INPUT_INTERFACE { + EFI_INPUT_RESET Reset; + EFI_INPUT_READ_KEY ReadKeyStroke; + EFI_EVENT WaitForKey; +} SIMPLE_INPUT_INTERFACE; + +#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ + {0xdd9e7534, 0x7762, 0x4698, {0x8c, 0x14, 0xf5, 0x85, \ + 0x17, 0xa6, 0x25, 0xaa} } + +INTERFACE_DECL(_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL); + +typedef UINT8 EFI_KEY_TOGGLE_STATE; +// +// Any Shift or Toggle State that is valid should have +// high order bit set. +// +typedef struct EFI_KEY_STATE { + UINT32 KeyShiftState; + EFI_KEY_TOGGLE_STATE KeyToggleState; +} EFI_KEY_STATE; + +typedef struct { + EFI_INPUT_KEY Key; + EFI_KEY_STATE KeyState; +} EFI_KEY_DATA; + +// +// Shift state +// +#define EFI_SHIFT_STATE_VALID 0x80000000 +#define EFI_RIGHT_SHIFT_PRESSED 0x00000001 +#define EFI_LEFT_SHIFT_PRESSED 0x00000002 +#define EFI_RIGHT_CONTROL_PRESSED 0x00000004 +#define EFI_LEFT_CONTROL_PRESSED 0x00000008 +#define EFI_RIGHT_ALT_PRESSED 0x00000010 +#define EFI_LEFT_ALT_PRESSED 0x00000020 +#define EFI_RIGHT_LOGO_PRESSED 0x00000040 +#define EFI_LEFT_LOGO_PRESSED 0x00000080 +#define EFI_MENU_KEY_PRESSED 0x00000100 +#define EFI_SYS_REQ_PRESSED 0x00000200 + +// +// Toggle state +// +#define EFI_TOGGLE_STATE_VALID 0x80 +#define EFI_KEY_STATE_EXPOSED 0x40 +#define EFI_SCROLL_LOCK_ACTIVE 0x01 +#define EFI_NUM_LOCK_ACTIVE 0x02 +#define EFI_CAPS_LOCK_ACTIVE 0x04 + +// +// EFI Key Notfication Function +// +typedef +EFI_STATUS +(EFIAPI *EFI_KEY_NOTIFY_FUNCTION) ( + IN EFI_KEY_DATA *KeyData + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_RESET_EX) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN BOOLEAN ExtendedVerification + ) +/*++ + + Routine Description: + Reset the input device and optionaly run diagnostics + + Arguments: + This - Protocol instance pointer. + ExtendedVerification - Driver may perform diagnostics on reset. + + Returns: + EFI_SUCCESS - The device was reset. + EFI_DEVICE_ERROR - The device is not functioning properly and could + not be reset. + +--*/ +; + +typedef +EFI_STATUS +(EFIAPI *EFI_INPUT_READ_KEY_EX) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + OUT EFI_KEY_DATA *KeyData + ) +/*++ + + Routine Description: + Reads the next keystroke from the input device. The WaitForKey Event can + be used to test for existence of a keystroke via WaitForEvent () call. + + Arguments: + This - Protocol instance pointer. + KeyData - A pointer to a buffer that is filled in with the keystroke + state data for the key that was pressed. + + Returns: + EFI_SUCCESS - The keystroke information was returned. + EFI_NOT_READY - There was no keystroke data availiable. + EFI_DEVICE_ERROR - The keystroke information was not returned due to + hardware errors. + EFI_INVALID_PARAMETER - KeyData is NULL. +--*/ +; + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_STATE) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_TOGGLE_STATE *KeyToggleState + ) +/*++ + + Routine Description: + Set certain state for the input device. + + Arguments: + This - Protocol instance pointer. + KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the + state for the input device. + + Returns: + EFI_SUCCESS - The device state was set successfully. + EFI_DEVICE_ERROR - The device is not functioning correctly and could + not have the setting adjusted. + EFI_UNSUPPORTED - The device does not have the ability to set its state. + EFI_INVALID_PARAMETER - KeyToggleState is NULL. + +--*/ +; + +typedef +EFI_STATUS +(EFIAPI *EFI_REGISTER_KEYSTROKE_NOTIFY) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_KEY_DATA *KeyData, + IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, + OUT EFI_HANDLE *NotifyHandle + ) +/*++ + + Routine Description: + Register a notification function for a particular keystroke for the input device. + + Arguments: + This - Protocol instance pointer. + KeyData - A pointer to a buffer that is filled in with the keystroke + information data for the key that was pressed. + KeyNotificationFunction - Points to the function to be called when the key + sequence is typed specified by KeyData. + NotifyHandle - Points to the unique handle assigned to the registered notification. + + Returns: + EFI_SUCCESS - The notification function was registered successfully. + EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures. + EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL. + +--*/ +; + +typedef +EFI_STATUS +(EFIAPI *EFI_UNREGISTER_KEYSTROKE_NOTIFY) ( + IN struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, + IN EFI_HANDLE NotificationHandle + ) +/*++ + + Routine Description: + Remove a registered notification function from a particular keystroke. + + Arguments: + This - Protocol instance pointer. + NotificationHandle - The handle of the notification function being unregistered. + + Returns: + EFI_SUCCESS - The notification function was unregistered successfully. + EFI_INVALID_PARAMETER - The NotificationHandle is invalid. + EFI_NOT_FOUND - Can not find the matching entry in database. + +--*/ +; + +typedef struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL { + EFI_INPUT_RESET_EX Reset; + EFI_INPUT_READ_KEY_EX ReadKeyStrokeEx; + EFI_EVENT WaitForKeyEx; + EFI_SET_STATE SetState; + EFI_REGISTER_KEYSTROKE_NOTIFY RegisterKeyNotify; + EFI_UNREGISTER_KEYSTROKE_NOTIFY UnregisterKeyNotify; +} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL; + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/eficonsctl.h b/bsps/shared/freebsd/stand/efi/include/eficonsctl.h new file mode 100644 index 0000000000..68be3d69f4 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/eficonsctl.h @@ -0,0 +1,134 @@ +/*- + * Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 HOLDER 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. + */ + +/* + * Original Module Name: ConsoleControl.h + * Abstract: Abstraction of a Text mode or GOP/UGA screen + */ + +/* $FreeBSD$ */ + +#ifndef _EFI_CONS_CTL_H +#define _EFI_CONS_CTL_H + +#define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \ + { 0xf42f7782, 0x12e, 0x4c12, {0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21} } + +typedef struct _EFI_CONSOLE_CONTROL_PROTOCOL EFI_CONSOLE_CONTROL_PROTOCOL; + + +typedef enum { + EfiConsoleControlScreenText, + EfiConsoleControlScreenGraphics, + EfiConsoleControlScreenMaxValue +} EFI_CONSOLE_CONTROL_SCREEN_MODE; + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode, + OUT BOOLEAN *GopUgaExists, OPTIONAL + OUT BOOLEAN *StdInLocked OPTIONAL + ) +/*++ + + Routine Description: + Return the current video mode information. Also returns info about existence + of Graphics Output devices or UGA Draw devices in system, and if the Std In + device is locked. All the arguments are optional and only returned if a non + NULL pointer is passed in. + + Arguments: + This - Protocol instance pointer. + Mode - Are we in text of grahics mode. + GopUgaExists - TRUE if Console Spliter has found a GOP or UGA device + StdInLocked - TRUE if StdIn device is keyboard locked + + Returns: + EFI_SUCCESS - Mode information returned. + +--*/ +; + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode + ) +/*++ + + Routine Description: + Set the current mode to either text or graphics. Graphics is + for Quiet Boot. + + Arguments: + This - Protocol instance pointer. + Mode - Mode to set the + + Returns: + EFI_SUCCESS - Mode information returned. + +--*/ +; + + +typedef +EFI_STATUS +(EFIAPI *EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN) ( + IN EFI_CONSOLE_CONTROL_PROTOCOL *This, + IN CHAR16 *Password + ) +/*++ + + Routine Description: + Lock Std In devices until Password is typed. + + Arguments: + This - Protocol instance pointer. + Password - Password needed to unlock screen. NULL means unlock keyboard + + Returns: + EFI_SUCCESS - Mode information returned. + EFI_DEVICE_ERROR - Std In not locked + +--*/ +; + + + +struct _EFI_CONSOLE_CONTROL_PROTOCOL { + EFI_CONSOLE_CONTROL_PROTOCOL_GET_MODE GetMode; + EFI_CONSOLE_CONTROL_PROTOCOL_SET_MODE SetMode; + EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn; +}; + +extern EFI_GUID gEfiConsoleControlProtocolGuid; + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efidef.h b/bsps/shared/freebsd/stand/efi/include/efidef.h new file mode 100644 index 0000000000..a8f88d41df --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efidef.h @@ -0,0 +1,224 @@ +/* $FreeBSD$ */ +#ifndef _EFI_DEF_H +#define _EFI_DEF_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efidef.h + +Abstract: + + EFI definitions + + + + +Revision History + +--*/ + +typedef UINT16 CHAR16; +typedef UINT8 CHAR8; +#ifndef ACPI_THREAD_ID /* ACPI's definitions are fine */ +typedef UINT8 BOOLEAN; +#endif + +#ifndef TRUE + #define TRUE ((BOOLEAN) 1) + #define FALSE ((BOOLEAN) 0) +#endif + +#ifndef NULL + #define NULL ((VOID *) 0) +#endif + +typedef UINTN EFI_STATUS; +typedef UINT64 EFI_LBA; +typedef UINTN EFI_TPL; +typedef VOID *EFI_HANDLE; +typedef VOID *EFI_EVENT; + + +// +// Prototype argument decoration for EFI parameters to indicate +// their direction +// +// IN - argument is passed into the function +// OUT - argument (pointer) is returned from the function +// OPTIONAL - argument is optional +// + +#ifndef IN + #define IN + #define OUT + #define OPTIONAL + #define CONST const +#endif + + +// +// A GUID +// + +typedef struct { + UINT32 Data1; + UINT16 Data2; + UINT16 Data3; + UINT8 Data4[8]; +} EFI_GUID; + + +// +// Time +// + +typedef struct { + UINT16 Year; // 1998 - 20XX + UINT8 Month; // 1 - 12 + UINT8 Day; // 1 - 31 + UINT8 Hour; // 0 - 23 + UINT8 Minute; // 0 - 59 + UINT8 Second; // 0 - 59 + UINT8 Pad1; + UINT32 Nanosecond; // 0 - 999,999,999 + INT16 TimeZone; // -1440 to 1440 or 2047 + UINT8 Daylight; + UINT8 Pad2; +} EFI_TIME; + +// Bit definitions for EFI_TIME.Daylight +#define EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define EFI_TIME_IN_DAYLIGHT 0x02 + +// Value definition for EFI_TIME.TimeZone +#define EFI_UNSPECIFIED_TIMEZONE 0x07FF + + + +// +// Networking +// + +typedef struct { + UINT8 Addr[4]; +} EFI_IPv4_ADDRESS; + +typedef struct { + UINT8 Addr[16]; +} EFI_IPv6_ADDRESS; + +typedef struct { + UINT8 Addr[32]; +} EFI_MAC_ADDRESS; + +typedef struct { + UINT32 ReceivedQueueTimeoutValue; + UINT32 TransmitQueueTimeoutValue; + UINT16 ProtocolTypeFilter; + BOOLEAN EnableUnicastReceive; + BOOLEAN EnableMulticastReceive; + BOOLEAN EnableBroadcastReceive; + BOOLEAN EnablePromiscuousReceive; + BOOLEAN FlushQueuesOnReset; + BOOLEAN EnableReceiveTimestamps; + BOOLEAN DisableBackgroundPolling; +} EFI_MANAGED_NETWORK_CONFIG_DATA; + +// +// Memory +// + +typedef UINT64 EFI_PHYSICAL_ADDRESS; +typedef UINT64 EFI_VIRTUAL_ADDRESS; + +typedef enum { + AllocateAnyPages, + AllocateMaxAddress, + AllocateAddress, + MaxAllocateType +} EFI_ALLOCATE_TYPE; + +//Preseve the attr on any range supplied. +//ConventialMemory must have WB,SR,SW when supplied. +//When allocating from ConventialMemory always make it WB,SR,SW +//When returning to ConventialMemory always make it WB,SR,SW +//When getting the memory map, or on RT for runtime types + + +typedef enum { + EfiReservedMemoryType, + EfiLoaderCode, + EfiLoaderData, + EfiBootServicesCode, + EfiBootServicesData, + EfiRuntimeServicesCode, + EfiRuntimeServicesData, + EfiConventionalMemory, + EfiUnusableMemory, + EfiACPIReclaimMemory, + EfiACPIMemoryNVS, + EfiMemoryMappedIO, + EfiMemoryMappedIOPortSpace, + EfiPalCode, + EfiPersistentMemory, + EfiMaxMemoryType +} EFI_MEMORY_TYPE; + +// possible caching types for the memory range +#define EFI_MEMORY_UC 0x0000000000000001 +#define EFI_MEMORY_WC 0x0000000000000002 +#define EFI_MEMORY_WT 0x0000000000000004 +#define EFI_MEMORY_WB 0x0000000000000008 +#define EFI_MEMORY_UCE 0x0000000000000010 + +// physical memory protection on range +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 +#define EFI_MEMORY_NV 0x0000000000008000 +#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000 +#define EFI_MEMORY_RO 0x0000000000020000 + +// range requires a runtime mapping +#define EFI_MEMORY_RUNTIME 0x8000000000000000 + +#define EFI_MEMORY_DESCRIPTOR_VERSION 1 +typedef struct { + UINT32 Type; // Field size is 32 bits followed by 32 bit pad + UINT32 Pad; + EFI_PHYSICAL_ADDRESS PhysicalStart; // Field size is 64 bits + EFI_VIRTUAL_ADDRESS VirtualStart; // Field size is 64 bits + UINT64 NumberOfPages; // Field size is 64 bits + UINT64 Attribute; // Field size is 64 bits +} EFI_MEMORY_DESCRIPTOR; + +// +// International Language +// + +typedef UINT8 ISO_639_2; +#define ISO_639_2_ENTRY_SIZE 3 + +// +// +// + +#define EFI_PAGE_SIZE 4096 +#define EFI_PAGE_MASK 0xFFF +#define EFI_PAGE_SHIFT 12 + +#define EFI_SIZE_TO_PAGES(a) \ + ( ((a) >> EFI_PAGE_SHIFT) + (((a) & EFI_PAGE_MASK) ? 1 : 0) ) + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efidevp.h b/bsps/shared/freebsd/stand/efi/include/efidevp.h new file mode 100644 index 0000000000..b00b78f02c --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efidevp.h @@ -0,0 +1,511 @@ +/* $FreeBSD$ */ +#ifndef _DEVPATH_H +#define _DEVPATH_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + devpath.h + +Abstract: + + Defines for parsing the EFI Device Path structures + + + +Revision History + +--*/ + +// +// Device Path structures - Section C +// + +#pragma pack(1) + +typedef struct _EFI_DEVICE_PATH { + UINT8 Type; + UINT8 SubType; + UINT8 Length[2]; +} EFI_DEVICE_PATH; + +#define EFI_DP_TYPE_MASK 0x7F +#define EFI_DP_TYPE_UNPACKED 0x80 + +#define END_DEVICE_PATH_TYPE 0x7f + +#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01 +#define END_DEVICE_PATH_LENGTH (sizeof(EFI_DEVICE_PATH)) + + +#define DP_IS_END_TYPE(a) +#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) + +#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK ) +#define DevicePathSubType(a) ( (a)->SubType ) +#define DevicePathNodeLength(a) ((size_t)(((a)->Length[0]) | ((a)->Length[1] << 8))) +#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a))) +#define IsDevicePathType(a, t) ( DevicePathType(a) == t ) +#define IsDevicePathEndType(a) IsDevicePathType(a, END_DEVICE_PATH_TYPE) +#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE ) +#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) ) +#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED ) + + +#define SetDevicePathNodeLength(a,l) { \ + (a)->Length[0] = (UINT8) (l); \ + (a)->Length[1] = (UINT8) ((l) >> 8); \ + } + +#define SetDevicePathEndNode(a) { \ + (a)->Type = END_DEVICE_PATH_TYPE; \ + (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \ + (a)->Length[0] = sizeof(EFI_DEVICE_PATH); \ + (a)->Length[1] = 0; \ + } + +/* + * + */ +#define HARDWARE_DEVICE_PATH 0x01 + +#define HW_PCI_DP 0x01 +typedef struct _PCI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 Function; + UINT8 Device; +} PCI_DEVICE_PATH; + +#define HW_PCCARD_DP 0x02 +typedef struct _PCCARD_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 FunctionNumber; +} PCCARD_DEVICE_PATH; + +#define HW_MEMMAP_DP 0x03 +typedef struct _MEMMAP_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 MemoryType; + EFI_PHYSICAL_ADDRESS StartingAddress; + EFI_PHYSICAL_ADDRESS EndingAddress; +} MEMMAP_DEVICE_PATH; + +#define HW_VENDOR_DP 0x04 +typedef struct _VENDOR_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_GUID Guid; +} VENDOR_DEVICE_PATH; + +#define UNKNOWN_DEVICE_GUID \ + { 0xcf31fac5, 0xc24e, 0x11d2, {0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b} } + +typedef struct _UKNOWN_DEVICE_VENDOR_DP { + VENDOR_DEVICE_PATH DevicePath; + UINT8 LegacyDriveLetter; +} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH; + +#define HW_CONTROLLER_DP 0x05 +typedef struct _CONTROLLER_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Controller; +} CONTROLLER_DEVICE_PATH; + +/* + * + */ +#define ACPI_DEVICE_PATH 0x02 + +#define ACPI_DP 0x01 +typedef struct _ACPI_HID_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 HID; + UINT32 UID; +} ACPI_HID_DEVICE_PATH; + +#define ACPI_EXTENDED_DP 0x02 +typedef struct _ACPI_EXTENDED_HID_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 HID; + UINT32 UID; + UINT32 CID; +} ACPI_EXTENDED_HID_DEVICE_PATH; + +#define ACPI_ADR_DP 0x03 +/* ACPI_ADR_DEVICE_PATH not defined */ + +// +// EISA ID Macro +// EISA ID Definition 32-bits +// bits[15:0] - three character compressed ASCII EISA ID. +// bits[31:16] - binary number +// Compressed ASCII is 5 bits per character 0b00001 = 'A' 0b11010 = 'Z' +// +#define PNP_EISA_ID_CONST 0x41d0 +#define EISA_ID(_Name, _Num) ((UINT32) ((_Name) | (_Num) << 16)) +#define EISA_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) +#define EFI_PNP_ID(_PNPId) (EISA_ID(PNP_EISA_ID_CONST, (_PNPId))) + +#define PNP_EISA_ID_MASK 0xffff +#define EISA_ID_TO_NUM(_Id) ((_Id) >> 16) +/* + * + */ +#define MESSAGING_DEVICE_PATH 0x03 + +#define MSG_ATAPI_DP 0x01 +typedef struct _ATAPI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 PrimarySecondary; + UINT8 SlaveMaster; + UINT16 Lun; +} ATAPI_DEVICE_PATH; + +#define MSG_SCSI_DP 0x02 +typedef struct _SCSI_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 Pun; + UINT16 Lun; +} SCSI_DEVICE_PATH; + +#define MSG_FIBRECHANNEL_DP 0x03 +typedef struct _FIBRECHANNEL_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 WWN; + UINT64 Lun; +} FIBRECHANNEL_DEVICE_PATH; + +#define MSG_1394_DP 0x04 +typedef struct _F1394_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 Guid; +} F1394_DEVICE_PATH; + +#define MSG_USB_DP 0x05 +typedef struct _USB_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT8 ParentPortNumber; + UINT8 InterfaceNumber; +} USB_DEVICE_PATH; + +#define MSG_USB_CLASS_DP 0x0F +typedef struct _USB_CLASS_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 VendorId; + UINT16 ProductId; + UINT8 DeviceClass; + UINT8 DeviceSubClass; + UINT8 DeviceProtocol; +} USB_CLASS_DEVICE_PATH; + +#define MSG_I2O_DP 0x06 +typedef struct _I2O_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Tid; +} I2O_DEVICE_PATH; + +#define MSG_MAC_ADDR_DP 0x0b +typedef struct _MAC_ADDR_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_MAC_ADDRESS MacAddress; + UINT8 IfType; +} MAC_ADDR_DEVICE_PATH; + +#define MSG_IPv4_DP 0x0c +typedef struct _IPv4_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_IPv4_ADDRESS LocalIpAddress; + EFI_IPv4_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; + EFI_IPv4_ADDRESS GatewayIpAddress; + EFI_IPv4_ADDRESS SubnetMask; +} IPv4_DEVICE_PATH; + +#define MSG_IPv6_DP 0x0d +typedef struct _IPv6_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_IPv6_ADDRESS LocalIpAddress; + EFI_IPv6_ADDRESS RemoteIpAddress; + UINT16 LocalPort; + UINT16 RemotePort; + UINT16 Protocol; + BOOLEAN StaticIpAddress; +} IPv6_DEVICE_PATH; + +#define MSG_INFINIBAND_DP 0x09 +typedef struct _INFINIBAND_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 ResourceFlags; + UINT8 PortGid[16]; + UINT64 ServiceId; + UINT64 TargetPortId; + UINT64 DeviceId; +} INFINIBAND_DEVICE_PATH; + +#define INFINIBAND_RESOURCE_FLAG_IOC_SERVICE 0x01 +#define INFINIBAND_RESOURCE_FLAG_EXTENDED_BOOT_ENVIRONMENT 0x02 +#define INFINIBAND_RESOURCE_FLAG_CONSOLE_PROTOCOL 0x04 +#define INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL 0x08 +#define INFINIBAND_RESOURCE_FLAG_NETWORK_PROTOCOL 0x10 + +#define MSG_UART_DP 0x0e +typedef struct _UART_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 Reserved; + UINT64 BaudRate; + UINT8 DataBits; + UINT8 Parity; + UINT8 StopBits; +} UART_DEVICE_PATH; + +#define MSG_VENDOR_DP 0x0A +/* Use VENDOR_DEVICE_PATH struct */ + +#define DEVICE_PATH_MESSAGING_PC_ANSI \ + { 0xe0c14753, 0xf9be, 0x11d2, {0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define DEVICE_PATH_MESSAGING_VT_100 \ + { 0xdfa66065, 0xb419, 0x11d3, {0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d} } + +#define DEVICE_PATH_MESSAGING_VT_100_PLUS \ + { 0x7baec70b, 0x57e0, 0x4c76, {0x8e, 0x87, 0x2f, 0x9e, 0x28, 0x08, 0x83, 0x43} } + +#define DEVICE_PATH_MESSAGING_VT_UTF8 \ + { 0xad15a0d6, 0x8bec, 0x4acf, {0xa0, 0x73, 0xd0, 0x1d, 0xe7, 0x7e, 0x2d, 0x88} } + +/* Device Logical Unit SubType. */ +#define MSG_DEVICE_LOGICAL_UNIT_DP 0x11 +typedef struct { + EFI_DEVICE_PATH Header; + /* Logical Unit Number for the interface. */ + UINT8 Lun; +} DEVICE_LOGICAL_UNIT_DEVICE_PATH; + +#define MSG_SATA_DP 0x12 +typedef struct _SATA_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 HBAPortNumber; + UINT16 PortMultiplierPortNumber; + UINT16 Lun; +} SATA_DEVICE_PATH; + + +/* DNS Device Path SubType */ +#define MSG_DNS_DP 0x1F +typedef struct { + EFI_DEVICE_PATH Header; + /* Indicates the DNS server address is IPv4 or IPv6 address. */ + UINT8 IsIPv6; + /* Instance of the DNS server address. */ + /* XXX: actually EFI_IP_ADDRESS */ + EFI_IPv4_ADDRESS DnsServerIp[]; +} DNS_DEVICE_PATH; + +/* Uniform Resource Identifiers (URI) Device Path SubType */ +#define MSG_URI_DP 0x18 +typedef struct { + EFI_DEVICE_PATH Header; + /* Instance of the URI pursuant to RFC 3986. */ + CHAR8 Uri[]; +} URI_DEVICE_PATH; + +#define MEDIA_DEVICE_PATH 0x04 + +#define MEDIA_HARDDRIVE_DP 0x01 +typedef struct _HARDDRIVE_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 PartitionNumber; + UINT64 PartitionStart; + UINT64 PartitionSize; + UINT8 Signature[16]; + UINT8 MBRType; + UINT8 SignatureType; +} HARDDRIVE_DEVICE_PATH; + +#define MBR_TYPE_PCAT 0x01 +#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02 + +#define SIGNATURE_TYPE_MBR 0x01 +#define SIGNATURE_TYPE_GUID 0x02 + +#define MEDIA_CDROM_DP 0x02 +typedef struct _CDROM_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT32 BootEntry; + UINT64 PartitionStart; + UINT64 PartitionSize; +} CDROM_DEVICE_PATH; + +#define MEDIA_VENDOR_DP 0x03 +/* Use VENDOR_DEVICE_PATH struct */ + +#define MEDIA_FILEPATH_DP 0x04 +typedef struct _FILEPATH_DEVICE_PATH { + EFI_DEVICE_PATH Header; + CHAR16 PathName[1]; +} FILEPATH_DEVICE_PATH; + +#define SIZE_OF_FILEPATH_DEVICE_PATH EFI_FIELD_OFFSET(FILEPATH_DEVICE_PATH,PathName) + +#define MEDIA_PROTOCOL_DP 0x05 +typedef struct _MEDIA_PROTOCOL_DEVICE_PATH { + EFI_DEVICE_PATH Header; + EFI_GUID Protocol; +} MEDIA_PROTOCOL_DEVICE_PATH; + + +#define BBS_DEVICE_PATH 0x05 +#define BBS_BBS_DP 0x01 +typedef struct _BBS_BBS_DEVICE_PATH { + EFI_DEVICE_PATH Header; + UINT16 DeviceType; + UINT16 StatusFlag; + CHAR8 String[1]; +} BBS_BBS_DEVICE_PATH; + +/* DeviceType definitions - from BBS specification */ +#define BBS_TYPE_FLOPPY 0x01 +#define BBS_TYPE_HARDDRIVE 0x02 +#define BBS_TYPE_CDROM 0x03 +#define BBS_TYPE_PCMCIA 0x04 +#define BBS_TYPE_USB 0x05 +#define BBS_TYPE_EMBEDDED_NETWORK 0x06 +#define BBS_TYPE_DEV 0x80 +#define BBS_TYPE_UNKNOWN 0xFF + +typedef union { + EFI_DEVICE_PATH DevPath; + PCI_DEVICE_PATH Pci; + PCCARD_DEVICE_PATH PcCard; + MEMMAP_DEVICE_PATH MemMap; + VENDOR_DEVICE_PATH Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor; + CONTROLLER_DEVICE_PATH Controller; + ACPI_HID_DEVICE_PATH Acpi; + + ATAPI_DEVICE_PATH Atapi; + SCSI_DEVICE_PATH Scsi; + FIBRECHANNEL_DEVICE_PATH FibreChannel; + + F1394_DEVICE_PATH F1394; + USB_DEVICE_PATH Usb; + USB_CLASS_DEVICE_PATH UsbClass; + I2O_DEVICE_PATH I2O; + MAC_ADDR_DEVICE_PATH MacAddr; + IPv4_DEVICE_PATH Ipv4; + IPv6_DEVICE_PATH Ipv6; + INFINIBAND_DEVICE_PATH InfiniBand; + UART_DEVICE_PATH Uart; + + HARDDRIVE_DEVICE_PATH HardDrive; + CDROM_DEVICE_PATH CD; + + FILEPATH_DEVICE_PATH FilePath; + MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol; + + BBS_BBS_DEVICE_PATH Bbs; + +} EFI_DEV_PATH; + +typedef union { + EFI_DEVICE_PATH *DevPath; + PCI_DEVICE_PATH *Pci; + PCCARD_DEVICE_PATH *PcCard; + MEMMAP_DEVICE_PATH *MemMap; + VENDOR_DEVICE_PATH *Vendor; + UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *UnknownVendor; + CONTROLLER_DEVICE_PATH *Controller; + ACPI_HID_DEVICE_PATH *Acpi; + ACPI_EXTENDED_HID_DEVICE_PATH *ExtendedAcpi; + + ATAPI_DEVICE_PATH *Atapi; + SCSI_DEVICE_PATH *Scsi; + FIBRECHANNEL_DEVICE_PATH *FibreChannel; + + F1394_DEVICE_PATH *F1394; + USB_DEVICE_PATH *Usb; + USB_CLASS_DEVICE_PATH *UsbClass; + I2O_DEVICE_PATH *I2O; + MAC_ADDR_DEVICE_PATH *MacAddr; + IPv4_DEVICE_PATH *Ipv4; + IPv6_DEVICE_PATH *Ipv6; + INFINIBAND_DEVICE_PATH *InfiniBand; + UART_DEVICE_PATH *Uart; + + HARDDRIVE_DEVICE_PATH *HardDrive; + + FILEPATH_DEVICE_PATH *FilePath; + MEDIA_PROTOCOL_DEVICE_PATH *MediaProtocol; + + CDROM_DEVICE_PATH *CD; + BBS_BBS_DEVICE_PATH *Bbs; + +} EFI_DEV_PATH_PTR; + +#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \ + { 0xbc62157e, 0x3e33, 0x4fec, { 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf } } + +#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ + { 0x8b843e20, 0x8132, 0x4852, { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } } + +#define EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ + { 0x05c99a21, 0xc70f, 0x4ad2, { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } } + +INTERFACE_DECL(_EFI_DEVICE_PATH_PROTOCOL); + +typedef +CHAR16* +(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE) ( + IN struct _EFI_DEVICE_PATH *This, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortCuts + ); + +typedef +CHAR16* +(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH) ( + IN struct _EFI_DEVICE_PATH *This, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortCuts + ); + +typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL { + EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText; + EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText; +} EFI_DEVICE_PATH_TO_TEXT_PROTOCOL; + +typedef +struct _EFI_DEVICE_PATH* +(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_NODE) ( + IN CONST CHAR16* TextDeviceNode + ); +typedef +struct _EFI_DEVICE_PATH* +(EFIAPI *EFI_DEVICE_PATH_FROM_TEXT_PATH) ( + IN CONST CHAR16* TextDevicePath + ); + + +typedef struct _EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL { + EFI_DEVICE_PATH_FROM_TEXT_NODE ConvertTextToDeviceNode; + EFI_DEVICE_PATH_FROM_TEXT_PATH ConvertTextToDevicePath; +} EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL; + +#pragma pack() + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efierr.h b/bsps/shared/freebsd/stand/efi/include/efierr.h new file mode 100644 index 0000000000..a8b6557185 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efierr.h @@ -0,0 +1,68 @@ +/* $FreeBSD$ */ +#ifndef _EFI_ERR_H +#define _EFI_ERR_H + +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efierr.h + +Abstract: + + EFI error codes + + + + +Revision History + +--*/ + + +#define EFIWARN(a) (a) +#define EFI_ERROR(a) (((INTN) a) < 0) +#define EFI_ERROR_CODE(a) (unsigned long)(a & ~EFI_ERROR_MASK) + + +#define EFI_SUCCESS 0 +#define EFI_LOAD_ERROR EFIERR(1) +#define EFI_INVALID_PARAMETER EFIERR(2) +#define EFI_UNSUPPORTED EFIERR(3) +#define EFI_BAD_BUFFER_SIZE EFIERR(4) +#define EFI_BUFFER_TOO_SMALL EFIERR(5) +#define EFI_NOT_READY EFIERR(6) +#define EFI_DEVICE_ERROR EFIERR(7) +#define EFI_WRITE_PROTECTED EFIERR(8) +#define EFI_OUT_OF_RESOURCES EFIERR(9) +#define EFI_VOLUME_CORRUPTED EFIERR(10) +#define EFI_VOLUME_FULL EFIERR(11) +#define EFI_NO_MEDIA EFIERR(12) +#define EFI_MEDIA_CHANGED EFIERR(13) +#define EFI_NOT_FOUND EFIERR(14) +#define EFI_ACCESS_DENIED EFIERR(15) +#define EFI_NO_RESPONSE EFIERR(16) +#define EFI_NO_MAPPING EFIERR(17) +#define EFI_TIMEOUT EFIERR(18) +#define EFI_NOT_STARTED EFIERR(19) +#define EFI_ALREADY_STARTED EFIERR(20) +#define EFI_ABORTED EFIERR(21) +#define EFI_ICMP_ERROR EFIERR(22) +#define EFI_TFTP_ERROR EFIERR(23) +#define EFI_PROTOCOL_ERROR EFIERR(24) + +#define EFI_WARN_UNKNOWN_GLYPH EFIWARN(1) +#define EFI_WARN_DELETE_FAILURE EFIWARN(2) +#define EFI_WARN_WRITE_FAILURE EFIWARN(3) +#define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4) + +#endif diff --git a/bsps/shared/freebsd/stand/efi/include/efigop.h b/bsps/shared/freebsd/stand/efi/include/efigop.h new file mode 100644 index 0000000000..104fa6e44b --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efigop.h @@ -0,0 +1,121 @@ +/* $FreeBSD$ */ +/*++ + +Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved +This software and associated documentation (if any) is furnished +under a license and may only be used or copied in accordance +with the terms of the license. Except as permitted by such +license, no part of this software or documentation may be +reproduced, stored in a retrieval system, or transmitted in any +form or by any means without the express written consent of +Intel Corporation. + +Module Name: + + efigop.h + +Abstract: + Info about framebuffers + + + + +Revision History + +--*/ + +#ifndef _EFIGOP_H +#define _EFIGOP_H + +#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \ + { 0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a} } + +INTERFACE_DECL(_EFI_GRAPHICS_OUTPUT); + +typedef struct { + UINT32 RedMask; + UINT32 GreenMask; + UINT32 BlueMask; + UINT32 ReservedMask; +} EFI_PIXEL_BITMASK; + +typedef enum { + PixelRedGreenBlueReserved8BitPerColor, + PixelBlueGreenRedReserved8BitPerColor, + PixelBitMask, + PixelBltOnly, + PixelFormatMax, +} EFI_GRAPHICS_PIXEL_FORMAT; + +typedef struct { + UINT32 Version; + UINT32 HorizontalResolution; + UINT32 VerticalResolution; + EFI_GRAPHICS_PIXEL_FORMAT PixelFormat; + EFI_PIXEL_BITMASK PixelInformation; + UINT32 PixelsPerScanLine; +} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION; + +typedef struct { + UINT32 MaxMode; + UINT32 Mode; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; + UINTN SizeOfInfo; + EFI_PHYSICAL_ADDRESS FrameBufferBase; + UINTN FrameBufferSize; +} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE; + +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE) ( + IN struct _EFI_GRAPHICS_OUTPUT *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE) ( + IN struct _EFI_GRAPHICS_OUTPUT *This, + IN UINT32 ModeNumber + ); + +typedef struct { + UINT8 Blue; + UINT8 Green; + UINT8 Red; + UINT8 Reserved; +} EFI_GRAPHICS_OUTPUT_BLT_PIXEL; + +typedef enum { + EfiBltVideoFill, + EfiBltVideoToBltBuffer, + EfiBltBufferToVideo, + EfiBltVideoToVideo, + EfiGraphcisOutputBltOperationMax, +} EFI_GRAPHICS_OUTPUT_BLT_OPERATION; + +typedef +EFI_STATUS +(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT) ( + IN struct _EFI_GRAPHICS_OUTPUT *This, + IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ); + +typedef struct _EFI_GRAPHICS_OUTPUT { + EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode; + EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode; + EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode; +} EFI_GRAPHICS_OUTPUT; + +#endif /* _EFIGOP_H */ diff --git a/bsps/shared/freebsd/stand/efi/include/efilib.h b/bsps/shared/freebsd/stand/efi/include/efilib.h new file mode 100644 index 0000000000..d31212ff9a --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/include/efilib.h @@ -0,0 +1,172 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * Copyright (c) 2006 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _LOADER_EFILIB_H +#define _LOADER_EFILIB_H + +#ifndef __rtems__ +#include <stand.h> +#endif /* __rtems__ */ +#include <stdbool.h> +#include <sys/queue.h> +#ifdef __rtems__ +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#endif /* __rtems__ */ + +extern EFI_HANDLE IH; +extern EFI_SYSTEM_TABLE *ST; +extern EFI_BOOT_SERVICES *BS; +extern EFI_RUNTIME_SERVICES *RS; + +#ifndef __rtems__ + +extern struct devsw efipart_fddev; +extern struct devsw efipart_cddev; +extern struct devsw efipart_hddev; +extern struct devsw efihttp_dev; +extern struct devsw efinet_dev; +extern struct netif_driver efinetif; + +/* EFI block device data, included here to help efi_zfs_probe() */ +typedef STAILQ_HEAD(pdinfo_list, pdinfo) pdinfo_list_t; + +typedef struct pdinfo +{ + STAILQ_ENTRY(pdinfo) pd_link; /* link in device list */ + pdinfo_list_t pd_part; /* list of partitions */ + EFI_HANDLE pd_handle; + EFI_HANDLE pd_alias; + EFI_DEVICE_PATH *pd_devpath; + EFI_BLOCK_IO *pd_blkio; + uint32_t pd_unit; /* unit number */ + uint32_t pd_open; /* reference counter */ + void *pd_bcache; /* buffer cache data */ + struct pdinfo *pd_parent; /* Linked items (eg partitions) */ + struct devsw *pd_devsw; /* Back pointer to devsw */ +} pdinfo_t; + +pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev); +pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev); +pdinfo_t *efiblk_get_pdinfo_by_handle(EFI_HANDLE h); +pdinfo_t *efiblk_get_pdinfo_by_device_path(EFI_DEVICE_PATH *path); + +/* libefi.c */ +void *efi_get_table(EFI_GUID *tbl); +EFI_STATUS OpenProtocolByHandle(EFI_HANDLE, EFI_GUID *, void **); + +static inline EFI_STATUS +efi_exit_boot_services(UINTN key) +{ + EFI_STATUS status; + + status = BS->ExitBootServices(IH, key); + if (!EFI_ERROR(status)) + boot_services_active = false; + return (status); +} + +int efi_getdev(void **vdev, const char *devspec, const char **path); + +int efi_register_handles(struct devsw *, EFI_HANDLE *, EFI_HANDLE *, int); +EFI_HANDLE efi_find_handle(struct devsw *, int); +int efi_handle_lookup(EFI_HANDLE, struct devsw **, int *, uint64_t *); +int efi_handle_update_dev(EFI_HANDLE, struct devsw *, int, uint64_t); + +EFI_DEVICE_PATH *efi_lookup_image_devpath(EFI_HANDLE); +EFI_DEVICE_PATH *efi_lookup_devpath(EFI_HANDLE); +void efi_close_devpath(EFI_HANDLE); +EFI_HANDLE efi_devpath_handle(EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_devpath_last_node(EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_devpath_trim(EFI_DEVICE_PATH *); +bool efi_devpath_match(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +bool efi_devpath_match_node(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +bool efi_devpath_is_prefix(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +CHAR16 *efi_devpath_name(EFI_DEVICE_PATH *); +void efi_free_devpath_name(CHAR16 *); +bool efi_devpath_same_disk(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_devpath_to_media_path(EFI_DEVICE_PATH *); +UINTN efi_devpath_length(EFI_DEVICE_PATH *); +EFI_DEVICE_PATH *efi_name_to_devpath(const char *path); +EFI_DEVICE_PATH *efi_name_to_devpath16(CHAR16 *path); +void efi_devpath_free(EFI_DEVICE_PATH *dp); +EFI_HANDLE efi_devpath_to_handle(EFI_DEVICE_PATH *path, EFI_HANDLE *handles, unsigned nhandles); + +int efi_status_to_errno(EFI_STATUS); +EFI_STATUS errno_to_efi_status(int errno); + +void efi_time_init(void); +void efi_time_fini(void); + +int parse_uefi_con_out(void); +EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab); + +EFI_STATUS main(int argc, CHAR16 *argv[]); +void efi_exit(EFI_STATUS status) __dead2; + +/* EFI environment initialization. */ +void efi_init_environment(void); + +/* EFI Memory type strings. */ +const char *efi_memory_type(EFI_MEMORY_TYPE); +#endif /* __rtems__ */ + +/* CHAR16 utility functions. */ +int wcscmp(CHAR16 *, CHAR16 *); +void cpy8to16(const char *, CHAR16 *, size_t); +void cpy16to8(const CHAR16 *, char *, size_t); + +#ifndef __rtems__ +/* + * Routines for interacting with EFI's env vars in a more unix-like + * way than the standard APIs. In addition, convenience routines for + * the loader setting / getting FreeBSD specific variables. + */ + +EFI_STATUS efi_delenv(EFI_GUID *guid, const char *varname); +EFI_STATUS efi_freebsd_delenv(const char *varname); +EFI_STATUS efi_freebsd_getenv(const char *v, void *data, __size_t *len); +EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, __size_t *len); +EFI_STATUS efi_global_getenv(const char *v, void *data, __size_t *len); +EFI_STATUS efi_setenv(EFI_GUID *guid, const char *varname, UINT32 attr, void *data, __size_t len); +EFI_STATUS efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr); + +/* guids and names */ +bool efi_guid_to_str(const EFI_GUID *, char **); +bool efi_str_to_guid(const char *, EFI_GUID *); +bool efi_name_to_guid(const char *, EFI_GUID *); +bool efi_guid_to_name(EFI_GUID *, char **); + +/* efipart.c */ +int efipart_inithandles(void); + +#endif /* __rtems__ */ + +#endif /* _LOADER_EFILIB_H */ diff --git a/bsps/shared/freebsd/stand/efi/libefi/libefi.c b/bsps/shared/freebsd/stand/efi/libefi/libefi.c new file mode 100644 index 0000000000..f63e146f2e --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/libefi/libefi.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2000 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efi.h> +#ifndef __rtems__ +#include <eficonsctl.h> +#include <efilib.h> +#include <stand.h> +#endif /* __rtems__ */ + +EFI_HANDLE IH; +EFI_SYSTEM_TABLE *ST; +EFI_BOOT_SERVICES *BS; +EFI_RUNTIME_SERVICES *RS; + +#ifndef __rtems__ +void * +efi_get_table(EFI_GUID *tbl) +{ + EFI_GUID *id; + int i; + + for (i = 0; i < ST->NumberOfTableEntries; i++) { + id = &ST->ConfigurationTable[i].VendorGuid; + if (!memcmp(id, tbl, sizeof(EFI_GUID))) + return (ST->ConfigurationTable[i].VendorTable); + } + return (NULL); +} + +EFI_STATUS +OpenProtocolByHandle(EFI_HANDLE handle, EFI_GUID *protocol, void **interface) +{ + return (BS->OpenProtocol(handle, protocol, interface, IH, NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); +} +#endif diff --git a/bsps/shared/freebsd/stand/efi/libefi/wchar.c b/bsps/shared/freebsd/stand/efi/libefi/wchar.c new file mode 100644 index 0000000000..d0c6535143 --- /dev/null +++ b/bsps/shared/freebsd/stand/efi/libefi/wchar.c @@ -0,0 +1,73 @@ +/*- + * Copyright 2016 Netflix, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 AUTHOR 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 AUTHOR 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <efi.h> +#include <efilib.h> + +/* + * CHAR16 related functions moved from loader. + * Perhaps we should move those to libsa afterall, but they are + * needed only by UEFI. + */ + +int +wcscmp(CHAR16 *a, CHAR16 *b) +{ + + while (*a && *b && *a == *b) { + a++; + b++; + } + return *a - *b; +} + +/* + * cpy8to16 copies a traditional C string into a CHAR16 string and + * 0 terminates it. len is the size of *dst in bytes. + */ +void +cpy8to16(const char *src, CHAR16 *dst, size_t len) +{ + len <<= 1; /* Assume CHAR16 is 2 bytes */ + while (len > 0 && *src) { + *dst++ = *src++; + len--; + } + *dst++ = (CHAR16)0; +} + +void +cpy16to8(const CHAR16 *src, char *dst, size_t len) +{ + size_t i; + + for (i = 0; i < len && src[i]; i++) + dst[i] = (char)src[i]; + if (i < len) + dst[i] = '\0'; +} diff --git a/bsps/shared/grlib/btimer/gptimer.c b/bsps/shared/grlib/btimer/gptimer.c index f31b7c052f..cbf058ccef 100644 --- a/bsps/shared/grlib/btimer/gptimer.c +++ b/bsps/shared/grlib/btimer/gptimer.c @@ -50,18 +50,15 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <rtems.h> -#include <bsp.h> -#include <stdlib.h> -#include <string.h> #include <drvmgr/drvmgr.h> #include <grlib/ambapp_bus.h> -#include <grlib/grlib.h> #include <grlib/gptimer.h> +#include <grlib/gptimer-regs.h> +#include <grlib/io.h> #include <grlib/tlib.h> #if defined(LEON3) -#include <leon.h> +#include <bsp/leon3.h> #endif #ifdef GPTIMER_INFO_AVAIL @@ -75,49 +72,21 @@ #include <grlib/grlib_impl.h> -/* GPTIMER Core Configuration Register (READ-ONLY) */ -#define GPTIMER_CFG_TIMERS_BIT 0 -#define GPTIMER_CFG_IRQ_BIT 3 -#define GPTIMER_CFG_SI_BIT 8 -#define GPTIMER_CFG_DF_BIT 9 - -#define GPTIMER_CFG_TIMERS (0x7<<GPTIMER_CFG_TIMERS_BIT) -#define GPTIMER_CFG_IRQ (0x1f<<GPTIMER_CFG_IRQ_BIT) -#define GPTIMER_CFG_SI (1<<GPTIMER_CFG_SI_BIT) -#define GPTIMER_CFG_DF (1<<GPTIMER_CFG_DF_BIT) - -/* GPTIMER Timer Control Register */ -#define GPTIMER_CTRL_EN_BIT 0 -#define GPTIMER_CTRL_RS_BIT 1 -#define GPTIMER_CTRL_LD_BIT 2 -#define GPTIMER_CTRL_IE_BIT 3 -#define GPTIMER_CTRL_IP_BIT 4 -#define GPTIMER_CTRL_CH_BIT 5 -#define GPTIMER_CTRL_DH_BIT 6 - -#define GPTIMER_CTRL_EN (1<<GPTIMER_CTRL_EN_BIT) -#define GPTIMER_CTRL_RS (1<<GPTIMER_CTRL_RS_BIT) -#define GPTIMER_CTRL_LD (1<<GPTIMER_CTRL_LD_BIT) -#define GPTIMER_CTRL_IE (1<<GPTIMER_CTRL_IE_BIT) -#define GPTIMER_CTRL_IP (1<<GPTIMER_CTRL_IP_BIT) -#define GPTIMER_CTRL_CH (1<<GPTIMER_CTRL_CH_BIT) -#define GPTIMER_CTRL_DH (1<<GPTIMER_CTRL_DH_BIT) - #define DBG(x...) /* GPTIMER timer private */ -struct gptimer_timer { +struct gptimer_timer_priv { struct tlib_dev tdev; /* Must be first in struct */ - struct gptimer_timer_regs *tregs; + gptimer_timer *tregs; char index; /* Timer Index in this driver */ char tindex; /* Timer Index In Hardware */ - unsigned char irq_ack_mask; + uint32_t irq_ack_mask; }; /* GPTIMER Core private */ struct gptimer_priv { struct drvmgr_dev *dev; - struct gptimer_regs *regs; + gptimer *regs; unsigned int base_clk; unsigned int base_freq; unsigned int widthmask; @@ -126,7 +95,7 @@ struct gptimer_priv { /* Structure per Timer unit, the core supports up to 8 timers */ int timer_cnt; - struct gptimer_timer timers[0]; + struct gptimer_timer_priv timers[0]; }; void gptimer_isr(void *data); @@ -200,14 +169,14 @@ void gptimer_register_drv (void) int gptimer_init1(struct drvmgr_dev *dev) { struct gptimer_priv *priv; - struct gptimer_regs *regs; + gptimer *regs; struct amba_dev_info *ambadev; struct ambapp_core *pnpinfo; int timer_hw_cnt, timer_cnt, timer_start; int i, size; - struct gptimer_timer *timer; + struct gptimer_timer_priv *timer; union drvmgr_key_value *value; - unsigned char irq_ack_mask; + uint32_t irq_ack_mask; /* Get device information from AMBA PnP information */ ambadev = (struct amba_dev_info *)dev->businfo; @@ -215,12 +184,12 @@ int gptimer_init1(struct drvmgr_dev *dev) return -1; } pnpinfo = &ambadev->info; - regs = (struct gptimer_regs *)pnpinfo->apb_slv->start; + regs = (gptimer *)pnpinfo->apb_slv->start; DBG("GPTIMER[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name); /* Get number of Timers */ - timer_hw_cnt = regs->cfg & GPTIMER_CFG_TIMERS; + timer_hw_cnt = GPTIMER_CONFIG_TIMERS_GET(grlib_load_32(®s->config)); /* Let user spelect a range of timers to be used. In AMP systems * it is sometimes neccessary to leave timers for other CPU instances. @@ -251,7 +220,7 @@ int gptimer_init1(struct drvmgr_dev *dev) * are present. */ size = sizeof(struct gptimer_priv) + - timer_cnt*sizeof(struct gptimer_timer); + timer_cnt*sizeof(struct gptimer_timer_priv); priv = dev->priv = grlib_calloc(1, size); if ( !priv ) return DRVMGR_NOMEM; @@ -277,24 +246,24 @@ int gptimer_init1(struct drvmgr_dev *dev) */ value = drvmgr_dev_key_get(priv->dev, "prescaler", DRVMGR_KT_INT); if ( value ) - regs->scaler_reload = value->i; + grlib_store_32(®s->sreload, value->i); /* Get Frequency that the timers are operating in (after prescaler) */ - priv->base_freq = priv->base_clk / (priv->regs->scaler_reload + 1); + priv->base_freq = priv->base_clk / (grlib_load_32(®s->sreload) + 1); /* Stop Timer and probe Pending bit. In newer hardware the * timer has pending bit is cleared by writing a one to it, * whereas older versions it is cleared with a zero. */ - priv->regs->timer[timer_start].ctrl = GPTIMER_CTRL_IP; - if ((priv->regs->timer[timer_start].ctrl & GPTIMER_CTRL_IP) != 0) - irq_ack_mask = ~GPTIMER_CTRL_IP; + grlib_store_32(®s->timer[timer_start].tctrl, GPTIMER_TCTRL_IP); + if ((grlib_load_32(®s->timer[timer_start].tctrl) & GPTIMER_TCTRL_IP) != 0) + irq_ack_mask = ~GPTIMER_TCTRL_IP; else - irq_ack_mask = ~0; + irq_ack_mask = ~0U; /* Probe timer register width mask */ - priv->regs->timer[timer_start].value = 0xffffffff; - priv->widthmask = priv->regs->timer[timer_start].value; + grlib_store_32(®s->timer[timer_start].tcntval, 0xffffffff); + priv->widthmask = grlib_load_32(®s->timer[timer_start].tcntval); priv->timer_cnt = timer_cnt; for (i=0; i<timer_cnt; i++) { @@ -314,7 +283,7 @@ int gptimer_init1(struct drvmgr_dev *dev) * B. Each Timer have an individual IRQ. The number is: * BASE_IRQ + timer_index */ - priv->separate_interrupt = (regs->cfg & GPTIMER_CFG_SI) != 0; + priv->separate_interrupt = (grlib_load_32(®s->config) & GPTIMER_CONFIG_SI) != 0; return DRVMGR_OK; } @@ -326,7 +295,7 @@ static int gptimer_info( void *p, int argc, char *argv[]) { struct gptimer_priv *priv = dev->priv; - struct gptimer_timer *timer; + struct gptimer_timer_priv *timer; char buf[64]; int i; @@ -337,7 +306,7 @@ static int gptimer_info( print_line(p, buf); sprintf(buf, "REGS: 0x%08x", (unsigned int)priv->regs); print_line(p, buf); - sprintf(buf, "BASE SCALER: %d", priv->regs->scaler_reload); + sprintf(buf, "BASE SCALER: %d", grlib_load_32(&priv->regs->sreload)); print_line(p, buf); sprintf(buf, "BASE FREQ: %dkHz", priv->base_freq / 1000); print_line(p, buf); @@ -350,9 +319,9 @@ static int gptimer_info( print_line(p, buf); sprintf(buf, " TLIB Index: %d", timer->index); print_line(p, buf); - sprintf(buf, " RELOAD REG: %d", timer->tregs->reload); + sprintf(buf, " RELOAD REG: %d", grlib_load_32(&timer->tregs->trldval)); print_line(p, buf); - sprintf(buf, " CTRL REG: %d", timer->tregs->ctrl); + sprintf(buf, " CTRL REG: %d", grlib_load_32(&timer->tregs->tctrl)); print_line(p, buf); } @@ -360,24 +329,28 @@ static int gptimer_info( } #endif -static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer *t) +static inline struct gptimer_priv *priv_from_timer(struct gptimer_timer_priv *t) { return (struct gptimer_priv *) ((unsigned int)t - sizeof(struct gptimer_priv) - - t->index * sizeof(struct gptimer_timer)); + t->index * sizeof(struct gptimer_timer_priv)); } static int gptimer_tlib_int_pend(struct tlib_dev *hand, int ack) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - unsigned int ctrl = timer->tregs->ctrl; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; + + tctrl = grlib_load_32(&timer->tregs->tctrl); - if ((ctrl & (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) == - (GPTIMER_CTRL_IP | GPTIMER_CTRL_IE)) { + if ((tctrl & (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) == + (GPTIMER_TCTRL_IP | GPTIMER_TCTRL_IE)) { /* clear Pending IRQ ? */ - if (ack) - timer->tregs->ctrl = ctrl & timer->irq_ack_mask; + if (ack) { + tctrl &= timer->irq_ack_mask; + grlib_store_32(&timer->tregs->tctrl, tctrl); + } return 1; /* timer generated IRQ */ } else return 0; /* was not timer causing IRQ */ @@ -406,12 +379,15 @@ void gptimer_isr(void *data) static void gptimer_tlib_reset(struct tlib_dev *hand) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - - timer->tregs->ctrl = (timer->tregs->ctrl & timer->irq_ack_mask) & - GPTIMER_CTRL_IP; - timer->tregs->reload = 0xffffffff; - timer->tregs->ctrl = GPTIMER_CTRL_LD; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; + + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= timer->irq_ack_mask; + tctrl &= GPTIMER_TCTRL_IP; + grlib_store_32(&timer->tregs->tctrl, tctrl); + grlib_store_32(&timer->tregs->trldval, 0xffffffff); + grlib_store_32(&timer->tregs->tctrl, GPTIMER_TCTRL_LD); } static void gptimer_tlib_get_freq( @@ -419,24 +395,24 @@ static void gptimer_tlib_get_freq( unsigned int *basefreq, unsigned int *tickrate) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); /* Calculate base frequency from Timer Clock and Prescaler */ if ( basefreq ) *basefreq = priv->base_freq; if ( tickrate ) - *tickrate = timer->tregs->reload + 1; + *tickrate = grlib_load_32(&timer->tregs->trldval) + 1; } static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; - timer->tregs->reload = tickrate - 1; + grlib_store_32(&timer->tregs->trldval, tickrate - 1); /*Check that value was allowed (Timer may not be as wide as expected)*/ - if ( timer->tregs->reload != (tickrate - 1) ) + if (grlib_load_32(&timer->tregs->trldval) != (tickrate - 1)) return -1; else return 0; @@ -444,8 +420,9 @@ static int gptimer_tlib_set_freq(struct tlib_dev *hand, unsigned int tickrate) static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *data, int flags) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); + uint32_t tctrl; if ( priv->separate_interrupt ) { drvmgr_interrupt_register(priv->dev, timer->tindex, @@ -476,16 +453,21 @@ static void gptimer_tlib_irq_reg(struct tlib_dev *hand, tlib_isr_t func, void *d } #endif - timer->tregs->ctrl |= GPTIMER_CTRL_IE; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl |= GPTIMER_TCTRL_IE; + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void *data) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); + uint32_t tctrl; /* Turn off IRQ at source, unregister IRQ handler */ - timer->tregs->ctrl &= ~GPTIMER_CTRL_IE; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= ~GPTIMER_TCTRL_IE; + grlib_store_32(&timer->tregs->tctrl, tctrl); if ( priv->separate_interrupt ) { drvmgr_interrupt_unregister(priv->dev, timer->tindex, @@ -502,46 +484,54 @@ static void gptimer_tlib_irq_unreg(struct tlib_dev *hand, tlib_isr_t func, void static void gptimer_tlib_start(struct tlib_dev *hand, int once) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; - unsigned int ctrl; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; /* Load the selected frequency before starting Frequency */ - ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_EN; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= timer->irq_ack_mask; + tctrl &= ~GPTIMER_TCTRL_RS; + tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN; if ( once == 0 ) - ctrl |= GPTIMER_CTRL_RS; /* Restart Timer */ - timer->tregs->ctrl = ctrl | (timer->tregs->ctrl & timer->irq_ack_mask & - ~GPTIMER_CTRL_RS); + tctrl |= GPTIMER_TCTRL_RS; /* Restart Timer */ + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_stop(struct tlib_dev *hand) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; /* Load the selected Frequency */ - timer->tregs->ctrl &= ~(GPTIMER_CTRL_EN|GPTIMER_CTRL_IP); + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl &= ~(GPTIMER_TCTRL_EN|GPTIMER_TCTRL_IP); + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_restart(struct tlib_dev *hand) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; + uint32_t tctrl; - timer->tregs->ctrl |= GPTIMER_CTRL_LD | GPTIMER_CTRL_EN; + tctrl = grlib_load_32(&timer->tregs->tctrl); + tctrl |= GPTIMER_TCTRL_LD | GPTIMER_TCTRL_EN; + grlib_store_32(&timer->tregs->tctrl, tctrl); } static void gptimer_tlib_get_counter( struct tlib_dev *hand, unsigned int *counter) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; - *counter = timer->tregs->value; + *counter = grlib_load_32(&timer->tregs->tcntval); } static void gptimer_tlib_get_widthmask( struct tlib_dev *hand, unsigned int *widthmask) { - struct gptimer_timer *timer = (struct gptimer_timer *)hand; + struct gptimer_timer_priv *timer = (struct gptimer_timer_priv *)hand; struct gptimer_priv *priv = priv_from_timer(timer); *widthmask = priv->widthmask; diff --git a/bsps/shared/grlib/btimer/tlib_ckinit.c b/bsps/shared/grlib/btimer/tlib_ckinit.c index 8a5ee33842..e2179090fa 100644 --- a/bsps/shared/grlib/btimer/tlib_ckinit.c +++ b/bsps/shared/grlib/btimer/tlib_ckinit.c @@ -433,10 +433,10 @@ static const struct ops ops_irqamp = { } \ } while (0) -#define Clock_driver_timecounter_tick() \ +#define Clock_driver_timecounter_tick(arg) \ tlib_clock_timecounter_tick() -#define Clock_driver_support_at_tick() \ +#define Clock_driver_support_at_tick(arg) \ do { \ rtems_device_driver ret; \ ret = tlib_clock_at_tick(); \ diff --git a/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c b/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c index 96b77907a6..35d23c1858 100644 --- a/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c +++ b/bsps/shared/grlib/drvmgr/ambapp_bus_grlib.c @@ -41,7 +41,7 @@ #include <grlib/genirq.h> #include <bsp.h> -#include <bsp/irq.h> +#include <bsp/irq-generic.h> #include <grlib/grlib_impl.h> @@ -227,7 +227,10 @@ static int ambapp_grlib_int_clear struct drvmgr_dev *dev, int irq) { - BSP_shared_interrupt_clear(irq); + if (rtems_interrupt_clear(irq) != RTEMS_SUCCESSFUL) { + return DRVMGR_FAIL; + } + return DRVMGR_OK; } @@ -237,7 +240,10 @@ static int ambapp_grlib_int_mask int irq ) { - BSP_shared_interrupt_mask(irq); + if (rtems_interrupt_vector_disable(irq) != RTEMS_SUCCESSFUL) { + return DRVMGR_FAIL; + } + return DRVMGR_OK; } @@ -247,7 +253,10 @@ static int ambapp_grlib_int_unmask int irq ) { - BSP_shared_interrupt_unmask(irq); + if (rtems_interrupt_vector_enable(irq) != RTEMS_SUCCESSFUL) { + return DRVMGR_FAIL; + } + return DRVMGR_OK; } diff --git a/bsps/shared/grlib/uart/apbuart_cons.c b/bsps/shared/grlib/uart/apbuart_cons.c index 5d47b7f4a1..a8b4eaaf88 100644 --- a/bsps/shared/grlib/uart/apbuart_cons.c +++ b/bsps/shared/grlib/uart/apbuart_cons.c @@ -47,11 +47,15 @@ #include <grlib/ambapp_bus.h> #include <grlib/apbuart.h> #include <grlib/ambapp.h> -#include <grlib/grlib.h> +#include <grlib/io.h> #include <grlib/cons.h> #include <rtems/termiostypes.h> #include <grlib/apbuart_cons.h> +#ifdef LEON3 +#include <bsp/leon3.h> +#endif + /*#define DEBUG 1 */ #ifdef DEBUG @@ -60,12 +64,6 @@ #define DBG(x...) #endif -/* LEON3 Low level transmit/receive functions provided by debug-uart code */ -#ifdef LEON3 -#include <leon.h> -extern struct apbuart_regs *leon3_debug_uart; /* The debug UART */ -#endif - /* Probed hardware capabilities */ enum { CAP_FIFO = 0x01, /* FIFO available */ @@ -74,7 +72,7 @@ enum { struct apbuart_priv { struct console_dev condev; struct drvmgr_dev *dev; - struct apbuart_regs *regs; + apbuart *regs; struct rtems_termios_tty *tty; char devName[52]; volatile int sending; @@ -213,18 +211,23 @@ static const rtems_termios_device_handler handler_polled = { * can select appropriate routines for the hardware. probecap() return value * is a CAP_ bitmask. */ -static int probecap(struct apbuart_regs *regs) +static int probecap(apbuart *regs) { int cap = 0; + uint32_t ctrl; /* Probe FIFO */ - if (regs->ctrl & APBUART_CTRL_FA) { + ctrl = grlib_load_32(®s->ctrl); + if (ctrl & APBUART_CTRL_FA) { cap |= CAP_FIFO; /* Probe RX delayed interrupt */ - regs->ctrl |= APBUART_CTRL_DI; - if (regs->ctrl & APBUART_CTRL_DI) { - regs->ctrl &= ~APBUART_CTRL_DI; + ctrl |= APBUART_CTRL_DI; + grlib_store_32(®s->ctrl, ctrl); + ctrl = grlib_load_32(®s->ctrl); + if (ctrl & APBUART_CTRL_DI) { + ctrl &= ~APBUART_CTRL_DI; + grlib_store_32(®s->ctrl, ctrl); cap |= CAP_DI; } } @@ -241,6 +244,7 @@ int apbuart_init1(struct drvmgr_dev *dev) char prefix[32]; unsigned int db; static int first_uart = 1; + uint32_t ctrl; /* The default operation in AMP is to use APBUART[0] for CPU[0], * APBUART[1] for CPU[1] and so on. The remaining UARTs is not used @@ -269,10 +273,12 @@ int apbuart_init1(struct drvmgr_dev *dev) if (ambadev == NULL) return -1; pnpinfo = &ambadev->info; - priv->regs = (struct apbuart_regs *)pnpinfo->apb_slv->start; + priv->regs = (apbuart *)pnpinfo->apb_slv->start; /* Clear HW regs, leave baudrate register as it is */ - priv->regs->status = 0; + grlib_store_32(&priv->regs->status, 0); + + ctrl = grlib_load_32(&priv->regs->ctrl); /* leave Transmitter/receiver if this is the RTEMS debug UART (assume * it has been setup by boot loader). @@ -280,10 +286,10 @@ int apbuart_init1(struct drvmgr_dev *dev) db = 0; #ifdef LEON3 if (priv->regs == leon3_debug_uart) { - db = priv->regs->ctrl & (APBUART_CTRL_RE | - APBUART_CTRL_TE | - APBUART_CTRL_PE | - APBUART_CTRL_PS); + db = ctrl & (APBUART_CTRL_RE | + APBUART_CTRL_TE | + APBUART_CTRL_PE | + APBUART_CTRL_PS); } #endif /* Let UART debug tunnelling be untouched if Flow-control is set. @@ -293,12 +299,12 @@ int apbuart_init1(struct drvmgr_dev *dev) * guess that we are debugging if FL is already set, the debugger set * either LB or DB depending on UART capabilities. */ - if (priv->regs->ctrl & APBUART_CTRL_FL) { - db |= priv->regs->ctrl & (APBUART_CTRL_DB | + if (ctrl & APBUART_CTRL_FL) { + db |= ctrl & (APBUART_CTRL_DB | APBUART_CTRL_LB | APBUART_CTRL_FL); } - priv->regs->ctrl = db; + grlib_store_32(&priv->regs->ctrl, db); priv->cap = probecap(priv->regs); @@ -387,12 +393,13 @@ static int apbuart_info( sprintf(buf, "FS Name: %s", priv->condev.fsname); print_line(p, buf); } - sprintf(buf, "STATUS REG: 0x%x", priv->regs->status); + sprintf(buf, "STATUS REG: 0x%x", grlib_load_32(&priv->regs->status)); print_line(p, buf); - sprintf(buf, "CTRL REG: 0x%x", priv->regs->ctrl); + sprintf(buf, "CTRL REG: 0x%x", grlib_load_32(&priv->regs->ctrl)); print_line(p, buf); sprintf(buf, "SCALER REG: 0x%x baud rate %d", - priv->regs->scaler, apbuart_get_baud(priv)); + grlib_load_32(&priv->regs->scaler), + apbuart_get_baud(priv)); print_line(p, buf); return DRVMGR_OK; @@ -407,6 +414,8 @@ static bool first_open( ) { struct apbuart_priv *uart = base_get_priv(base); + apbuart *regs = uart->regs; + uint32_t ctrl; uart->tty = tty; @@ -418,11 +427,11 @@ static bool first_open( } /* Enable TX/RX */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + ctrl = grlib_load_32(®s->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; if (uart->mode != TERMIOS_POLLED) { int ret; - uint32_t ctrl; /* Register interrupt and enable it */ ret = drvmgr_interrupt_register( @@ -435,15 +444,15 @@ static bool first_open( uart->sending = 0; /* Turn on RX interrupts */ - ctrl = uart->regs->ctrl; ctrl |= APBUART_CTRL_RI; if (uart->cap & CAP_DI) { /* Use RX FIFO interrupt only if delayed interrupt available. */ ctrl |= (APBUART_CTRL_DI | APBUART_CTRL_RF); } - uart->regs->ctrl = ctrl; } + grlib_store_32(®s->ctrl, ctrl); + return true; } @@ -454,13 +463,16 @@ static void last_close( ) { struct apbuart_priv *uart = base_get_priv(base); + apbuart *regs = uart->regs; rtems_interrupt_lock_context lock_context; + uint32_t ctrl; if (uart->mode != TERMIOS_POLLED) { /* Turn off RX interrupts */ rtems_termios_device_lock_acquire(base, &lock_context); - uart->regs->ctrl &= - ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /**** Flush device ****/ @@ -468,8 +480,8 @@ static void last_close( /* Wait until all data has been sent */ } while ( - (uart->regs->ctrl & APBUART_CTRL_TE) && - !(uart->regs->status & APBUART_STATUS_TS) + (grlib_load_32(®s->ctrl) & APBUART_CTRL_TE) && + !(grlib_load_32(®s->status) & APBUART_STATUS_TS) ) { /* Wait until all data has left shift register */ } @@ -480,8 +492,11 @@ static void last_close( #ifdef LEON3 /* Disable TX/RX if not used for DEBUG */ - if (uart->regs != leon3_debug_uart) - uart->regs->ctrl &= ~(APBUART_CTRL_RE | APBUART_CTRL_TE); + if (regs != leon3_debug_uart) { + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_RE | APBUART_CTRL_TE); + grlib_store_32(®s->ctrl, ctrl); + } #endif } @@ -497,10 +512,11 @@ static int read_task(rtems_termios_device_context *base) { rtems_interrupt_lock_context lock_context; struct apbuart_priv *uart = base_get_priv(base); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; int cnt; char buf[33]; struct rtems_termios_tty *tty; + uint32_t ctrl; uint32_t ctrl_add; ctrl_add = APBUART_CTRL_RI; @@ -511,10 +527,10 @@ static int read_task(rtems_termios_device_context *base) do { cnt = 0; while ( - (regs->status & APBUART_STATUS_DR) && + (grlib_load_32(®s->status) & APBUART_STATUS_DR) && (cnt < sizeof(buf)) ) { - buf[cnt] = regs->data; + buf[cnt] = grlib_load_32(®s->data); cnt++; } if (0 < cnt) { @@ -528,9 +544,11 @@ static int read_task(rtems_termios_device_context *base) * afterwards. */ rtems_termios_device_lock_acquire(base, &lock_context); - regs->ctrl |= ctrl_add; + ctrl = grlib_load_32(®s->ctrl); + ctrl |= ctrl_add; + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); - } while (regs->status & APBUART_STATUS_DR); + } while (grlib_load_32(®s->status) & APBUART_STATUS_DR); return EOF; } @@ -541,7 +559,7 @@ int apbuart_get_baud(struct apbuart_priv *uart) unsigned int scaler; /* Get current scaler setting */ - scaler = uart->regs->scaler; + scaler = grlib_load_32(&uart->regs->scaler); /* Get APBUART core frequency */ drvmgr_freq_get(uart->dev, DEV_APB_SLV, &core_clk_hz); @@ -576,7 +594,7 @@ static bool set_attributes( rtems_termios_device_lock_acquire(base, &lock_context); /* Read out current value */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); switch(t->c_cflag & (PARENB|PARODD)){ case (PARENB|PARODD): @@ -603,7 +621,7 @@ static bool set_attributes( ctrl &= ~APBUART_CTRL_FL; /* Update new settings */ - uart->regs->ctrl = ctrl; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); @@ -617,7 +635,7 @@ static bool set_attributes( scaler = (((core_clk_hz*10)/(baud*8))-5)/10; /* Set new baud rate by setting scaler */ - uart->regs->scaler = scaler; + grlib_store_32(&uart->regs->scaler, scaler); } return true; @@ -637,7 +655,7 @@ static void get_attributes( t->c_cflag |= CS8; /* Read out current parity */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); if (ctrl & APBUART_CTRL_PE) { if (ctrl & APBUART_CTRL_PS) t->c_cflag |= PARENB|PARODD; /* Odd parity */ @@ -673,11 +691,11 @@ static void write_interrupt( ) { struct apbuart_priv *uart = base_get_priv(base); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; int sending; unsigned int ctrl; - ctrl = regs->ctrl; + ctrl = grlib_load_32(®s->ctrl); if (len > 0) { /* @@ -685,28 +703,30 @@ static void write_interrupt( * we can tell termios later. */ /* Enable TX interrupt (interrupt is edge-triggered) */ - regs->ctrl = ctrl | APBUART_CTRL_TI; + ctrl |= APBUART_CTRL_TI; + grlib_store_32(®s->ctrl, ctrl); if (ctrl & APBUART_CTRL_FA) { /* APBUART with FIFO.. Fill as many as FIFO allows */ sending = 0; while ( - ((regs->status & APBUART_STATUS_TF) == 0) && + ((grlib_load_32(®s->status) & APBUART_STATUS_TF) == 0) && (sending < len) ) { - regs->data = *buf; + grlib_store_32(®s->data, *buf); buf++; sending++; } } else { /* start UART TX, this will result in an interrupt when done */ - regs->data = *buf; + grlib_store_32(®s->data, *buf); sending = 1; } } else { /* No more to send, disable TX interrupts */ - regs->ctrl = ctrl & ~APBUART_CTRL_TI; + ctrl &= ~APBUART_CTRL_TI; + grlib_store_32(®s->ctrl, ctrl); /* Tell close that we sent everything */ sending = 0; @@ -722,21 +742,24 @@ static void apbuart_cons_isr(void *arg) rtems_termios_device_context *base; struct console_dev *condev = rtems_termios_get_device_context(tty); struct apbuart_priv *uart = condev_get_priv(condev); - struct apbuart_regs *regs = uart->regs; + apbuart *regs = uart->regs; unsigned int status; char buf[33]; int cnt; if (uart->mode == TERMIOS_TASK_DRIVEN) { - if ((status = regs->status) & APBUART_STATUS_DR) { + if ((status = grlib_load_32(®s->status)) & APBUART_STATUS_DR) { rtems_interrupt_lock_context lock_context; + uint32_t ctrl; /* Turn off RX interrupts */ base = rtems_termios_get_device_context(tty); rtems_termios_device_lock_acquire(base, &lock_context); - regs->ctrl &= + ctrl = grlib_load_32(®s->ctrl); + ctrl &= ~(APBUART_CTRL_DI | APBUART_CTRL_RI | APBUART_CTRL_RF); + grlib_store_32(®s->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /* Activate termios RX daemon task */ rtems_termios_rxirq_occured(tty); @@ -749,10 +772,10 @@ static void apbuart_cons_isr(void *arg) */ cnt = 0; while ( - ((status=regs->status) & APBUART_STATUS_DR) && + ((status=grlib_load_32(®s->status)) & APBUART_STATUS_DR) && (cnt < sizeof(buf)) ) { - buf[cnt] = regs->data; + buf[cnt] = grlib_load_32(®s->data); cnt++; } if (0 < cnt) { diff --git a/bsps/shared/grlib/uart/apbuart_polled.c b/bsps/shared/grlib/uart/apbuart_polled.c index b83af56b09..84c31795df 100644 --- a/bsps/shared/grlib/uart/apbuart_polled.c +++ b/bsps/shared/grlib/uart/apbuart_polled.c @@ -1,8 +1,17 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSDeviceGRLIBAPBUART + * + * @brief This source file contains the implementation of + * apbuart_outbyte_wait(), apbuart_outbyte_polled(), and + * apbuart_inbyte_nonblocking(). + */ + /* - * COPYRIGHT (c) 2010. - * Cobham Gaisler AB. + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,38 +36,37 @@ */ #include <grlib/apbuart.h> +#include <grlib/io.h> -#include <rtems/score/cpuimpl.h> +#include <rtems/dev/io.h> -void apbuart_outbyte_wait(const struct apbuart_regs *regs) +void apbuart_outbyte_wait( const apbuart *regs ) { - while ( (regs->status & APBUART_STATUS_TE) == 0 ) { - /* Lower bus utilization while waiting for UART */ - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); - _CPU_Instruction_no_operation(); + while ( ( grlib_load_32( ®s->status ) & APBUART_STATUS_TE ) == 0 ) { + _IO_Relax(); } } -void apbuart_outbyte_polled(struct apbuart_regs *regs, char ch) +void apbuart_outbyte_polled( apbuart *regs, char ch) { - apbuart_outbyte_wait(regs); - regs->data = (uint8_t) ch; + apbuart_outbyte_wait( regs ); + grlib_store_32( ®s->data, (uint8_t) ch ); } -int apbuart_inbyte_nonblocking(struct apbuart_regs *regs) +int apbuart_inbyte_nonblocking( apbuart *regs ) { - /* Clear errors */ - regs->status = ~APBUART_STATUS_ERR; + uint32_t status; + + status = grlib_load_32( ®s->status ); + + /* Clear errors, writes to non-error flags are ignored */ + status &= ~( APBUART_STATUS_FE | APBUART_STATUS_PE | APBUART_STATUS_OV | + APBUART_STATUS_BR ); + grlib_store_32( ®s->status, status ); - if ((regs->status & APBUART_STATUS_DR) == 0) { + if ( ( status & APBUART_STATUS_DR ) == 0 ) { return -1; } - return (uint8_t) regs->data; + return (int) APBUART_DATA_DATA_GET( grlib_load_32( ®s->data ) ); } diff --git a/bsps/shared/grlib/uart/apbuart_termios.c b/bsps/shared/grlib/uart/apbuart_termios.c index 6506b70e3d..8b5ccd67f6 100644 --- a/bsps/shared/grlib/uart/apbuart_termios.c +++ b/bsps/shared/grlib/uart/apbuart_termios.c @@ -32,6 +32,7 @@ #include <grlib/apbuart_termios.h> #include <grlib/apbuart.h> +#include <grlib/io.h> #include <bsp.h> static void apbuart_isr(void *arg) @@ -42,9 +43,9 @@ static void apbuart_isr(void *arg) char data; /* Get all received characters */ - while ((status=uart->regs->status) & APBUART_STATUS_DR) { + while ((status=grlib_load_32(&uart->regs->status)) & APBUART_STATUS_DR) { /* Data has arrived, get new data */ - data = uart->regs->data; + data = (char)grlib_load_32(&uart->regs->data); /* Tell termios layer about new character */ rtems_termios_enqueue_raw_characters(tty, &data, 1); @@ -52,7 +53,7 @@ static void apbuart_isr(void *arg) if ( (status & APBUART_STATUS_TE) - && (uart->regs->ctrl & APBUART_CTRL_TI) != 0 + && (grlib_load_32(&uart->regs->ctrl) & APBUART_CTRL_TI) != 0 ) { /* write_interrupt will get called from this function */ rtems_termios_dequeue_characters(tty, 1); @@ -67,23 +68,27 @@ static void apbuart_write_support( { struct apbuart_context *uart = (struct apbuart_context *) base; int sending; + uint32_t ctrl; + + ctrl = grlib_load_32(&uart->regs->ctrl); if (len > 0) { /* Enable TX interrupt (interrupt is edge-triggered) */ - uart->regs->ctrl |= APBUART_CTRL_TI; + ctrl |= APBUART_CTRL_TI; /* start UART TX, this will result in an interrupt when done */ - uart->regs->data = *buf; + grlib_store_32(&uart->regs->data, (uint8_t)*buf); sending = 1; } else { /* No more to send, disable TX interrupts */ - uart->regs->ctrl &= ~APBUART_CTRL_TI; + ctrl &= ~APBUART_CTRL_TI; /* Tell close that we sent everything */ sending = 0; } + grlib_store_32(&uart->regs->ctrl, ctrl); uart->sending = sending; } @@ -134,7 +139,7 @@ static bool apbuart_set_attributes( rtems_termios_device_lock_acquire(base, &lock_context); /* Read out current value */ - ctrl = uart->regs->ctrl; + ctrl = grlib_load_32(&uart->regs->ctrl); switch (t->c_cflag & (PARENB|PARODD)) { case (PARENB|PARODD): @@ -162,7 +167,7 @@ static bool apbuart_set_attributes( } /* Update new settings */ - uart->regs->ctrl = ctrl; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); @@ -173,7 +178,7 @@ static bool apbuart_set_attributes( scaler = (((uart->freq_hz * 10) / (baud * 8)) - 5) / 10; /* Set new baud rate by setting scaler */ - uart->regs->scaler = scaler; + grlib_store_32(&uart->regs->scaler, scaler); } return true; @@ -184,7 +189,8 @@ static void apbuart_set_best_baud( struct termios *term ) { - uint32_t baud = (uart->freq_hz * 10) / ((uart->regs->scaler * 10 + 5) * 8); + uint32_t baud = (uart->freq_hz * 10) / + ((grlib_load_32(&uart->regs->scaler) * 10 + 5) * 8); rtems_termios_set_best_baud(term, baud); } @@ -197,12 +203,15 @@ static bool apbuart_first_open_polled( ) { struct apbuart_context *uart = (struct apbuart_context *) base; + uint32_t ctrl; apbuart_set_best_baud(uart, term); /* Initialize UART on opening */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - uart->regs->status = 0; + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&uart->regs->ctrl, ctrl); + grlib_store_32(&uart->regs->status, 0); return true; } @@ -216,6 +225,7 @@ static bool apbuart_first_open_interrupt( { struct apbuart_context *uart = (struct apbuart_context *) base; rtems_status_code sc; + uint32_t ctrl; apbuart_set_best_baud(uart, term); @@ -229,11 +239,13 @@ static bool apbuart_first_open_interrupt( uart->sending = 0; /* Enable Receiver and transmitter and Turn on RX interrupts */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE | - APBUART_CTRL_RI; + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE | APBUART_CTRL_RI; + grlib_store_32(&uart->regs->ctrl, ctrl); /* Initialize UART on opening */ - uart->regs->ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; - uart->regs->status = 0; + ctrl |= APBUART_CTRL_RE | APBUART_CTRL_TE; + grlib_store_32(&uart->regs->ctrl, ctrl); + grlib_store_32(&uart->regs->status, 0); return true; } @@ -246,10 +258,13 @@ static void apbuart_last_close_interrupt( { struct apbuart_context *uart = (struct apbuart_context *) base; rtems_interrupt_lock_context lock_context; + uint32_t ctrl; /* Turn off RX interrupts */ rtems_termios_device_lock_acquire(base, &lock_context); - uart->regs->ctrl &= ~(APBUART_CTRL_RI); + ctrl = grlib_load_32(&uart->regs->ctrl); + ctrl &= ~APBUART_CTRL_RI; + grlib_store_32(&uart->regs->ctrl, ctrl); rtems_termios_device_lock_release(base, &lock_context); /**** Flush device ****/ diff --git a/bsps/shared/irq/irq-affinity.c b/bsps/shared/irq/irq-affinity.c index dc105639c3..7e9250a948 100644 --- a/bsps/shared/irq/irq-affinity.c +++ b/bsps/shared/irq/irq-affinity.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2017, 2022 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2017, 2022 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -36,7 +36,6 @@ #include <bsp/irq-generic.h> -#include <rtems/score/processormask.h> #include <rtems/score/smpimpl.h> rtems_status_code rtems_interrupt_set_affinity( diff --git a/bsps/shared/irq/irq-default-handler.c b/bsps/shared/irq/irq-default-handler.c index 1458ceae40..3f765a2a64 100644 --- a/bsps/shared/irq/irq-default-handler.c +++ b/bsps/shared/irq/irq-default-handler.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2008, 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-default.c b/bsps/shared/irq/irq-default.c index 39ee11118c..7210235aa6 100644 --- a/bsps/shared/irq/irq-default.c +++ b/bsps/shared/irq/irq-default.c @@ -11,7 +11,7 @@ */ /* - * Copyright (C) 2019 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2019 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-enable-disable.c b/bsps/shared/irq/irq-enable-disable.c index c9602de398..2e0a675b85 100644 --- a/bsps/shared/irq/irq-enable-disable.c +++ b/bsps/shared/irq/irq-enable-disable.c @@ -11,7 +11,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-entry-remove.c b/bsps/shared/irq/irq-entry-remove.c index 6f603359fd..d2f290d595 100644 --- a/bsps/shared/irq/irq-entry-remove.c +++ b/bsps/shared/irq/irq-entry-remove.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-generic.c b/bsps/shared/irq/irq-generic.c index cf99b7207d..b6238025b7 100644 --- a/bsps/shared/irq/irq-generic.c +++ b/bsps/shared/irq/irq-generic.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2008, 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,9 +35,6 @@ */ #include <bsp/irq-generic.h> -#include <bsp/fatal.h> - -#include <stdlib.h> #include <rtems/malloc.h> @@ -66,9 +63,7 @@ static inline void bsp_interrupt_set_initialized(void) } #if defined(BSP_INTERRUPT_USE_INDEX_TABLE) -static inline rtems_vector_number bsp_interrupt_allocate_handler_index( - rtems_vector_number vector -) +static inline rtems_vector_number bsp_interrupt_allocate_handler_index( void ) { rtems_vector_number i; @@ -180,7 +175,7 @@ static rtems_status_code bsp_interrupt_entry_install_first( rtems_vector_number index; #ifdef BSP_INTERRUPT_USE_INDEX_TABLE - index = bsp_interrupt_allocate_handler_index( vector ); + index = bsp_interrupt_allocate_handler_index(); if ( index == BSP_INTERRUPT_DISPATCH_TABLE_SIZE ) { /* Handler table is full */ diff --git a/bsps/shared/irq/irq-handler-install.c b/bsps/shared/irq/irq-handler-install.c index 75cd2c9822..18c4cbf3a7 100644 --- a/bsps/shared/irq/irq-handler-install.c +++ b/bsps/shared/irq/irq-handler-install.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-handler-iterate.c b/bsps/shared/irq/irq-handler-iterate.c index f7af6ee356..770318cc68 100644 --- a/bsps/shared/irq/irq-handler-iterate.c +++ b/bsps/shared/irq/irq-handler-iterate.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2017, 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2017, 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-handler-remove.c b/bsps/shared/irq/irq-handler-remove.c index ab46c67ab1..a01af46455 100644 --- a/bsps/shared/irq/irq-handler-remove.c +++ b/bsps/shared/irq/irq-handler-remove.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-info.c b/bsps/shared/irq/irq-info.c index 8738771a43..c4cbd96acf 100644 --- a/bsps/shared/irq/irq-info.c +++ b/bsps/shared/irq/irq-info.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2008, 2010 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2010 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-legacy.c b/bsps/shared/irq/irq-legacy.c index 6181b0c994..ee4d11cd87 100644 --- a/bsps/shared/irq/irq-legacy.c +++ b/bsps/shared/irq/irq-legacy.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2008, 2009 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2009 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-lock.c b/bsps/shared/irq/irq-lock.c index 568443718a..8090ade84e 100644 --- a/bsps/shared/irq/irq-lock.c +++ b/bsps/shared/irq/irq-lock.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2008, 2018 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2008, 2018 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-raise-clear.c b/bsps/shared/irq/irq-raise-clear.c index 042c1a2b7a..e06f79658b 100644 --- a/bsps/shared/irq/irq-raise-clear.c +++ b/bsps/shared/irq/irq-raise-clear.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-record.c b/bsps/shared/irq/irq-record.c index f48c0c732c..15bb20132d 100644 --- a/bsps/shared/irq/irq-record.c +++ b/bsps/shared/irq/irq-record.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2022 embedded brains GmbH + * Copyright (C) 2022 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-server.c b/bsps/shared/irq/irq-server.c index d099c6ff05..bac54316d1 100644 --- a/bsps/shared/irq/irq-server.c +++ b/bsps/shared/irq/irq-server.c @@ -9,7 +9,7 @@ */ /* - * Copyright (C) 2009, 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2009, 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/irq/irq-shell.c b/bsps/shared/irq/irq-shell.c index 2667924076..a56fa938cf 100644 --- a/bsps/shared/irq/irq-shell.c +++ b/bsps/shared/irq/irq-shell.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2009 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2009 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/rtems-version.c b/bsps/shared/rtems-version.c index b12504a1c9..aaac5a07f3 100644 --- a/bsps/shared/rtems-version.c +++ b/bsps/shared/rtems-version.c @@ -1,3 +1,12 @@ +/** + * @file + * + * @ingroup RTEMSImplClassic + * + * @brief This source file contains the implementation of + * rtems_board_support_package() and the definition of ::_RTEMS_version. + */ + /* * COPYRIGHT (c) 2003, Ralf Corsepius, Ulm, Germany. * COPYRIGHT (c) 2003, On-Line Applications Research Corporation (OAR). diff --git a/bsps/shared/start/bsp-fdt.c b/bsps/shared/start/bsp-fdt.c index f532247b2a..79f31733e1 100644 --- a/bsps/shared/start/bsp-fdt.c +++ b/bsps/shared/start/bsp-fdt.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved. + * Copyright (C) 2015, 2017 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/bsp-uboot-board-info.c b/bsps/shared/start/bsp-uboot-board-info.c index 29ae573fd7..39828b1a9d 100644 --- a/bsps/shared/start/bsp-uboot-board-info.c +++ b/bsps/shared/start/bsp-uboot-board-info.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2010, 2016 embedded brains GmbH. All rights reserved. + * Copyright (C) 2010, 2016 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/bspfatal-default.c b/bsps/shared/start/bspfatal-default.c index 9e109c4eb7..557a0960fa 100644 --- a/bsps/shared/start/bspfatal-default.c +++ b/bsps/shared/start/bspfatal-default.c @@ -1,5 +1,14 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup RTEMSBSPsShared + * + * @brief This source file contains the implementation of + * bsp_fatal_extension(). + */ + /* * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). diff --git a/bsps/shared/start/bspgetworkarea-default.c b/bsps/shared/start/bspgetworkarea-default.c index 5686b013f9..5f956b124f 100644 --- a/bsps/shared/start/bspgetworkarea-default.c +++ b/bsps/shared/start/bspgetworkarea-default.c @@ -12,7 +12,7 @@ */ /* - * Copyright (C) 2011, 2019 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2011, 2019 embedded brains GmbH & Co. KG * * Copyright (C) 1989, 2009 On-Line Applications Research Corporation (OAR) * @@ -39,7 +39,6 @@ */ #include <bsp.h> -#include <bsp/bootcard.h> #if defined(HAS_UBOOT) && !defined(BSP_DISABLE_UBOOT_WORK_AREA_CONFIG) #define USE_UBOOT diff --git a/bsps/shared/start/gettargethash-default.c b/bsps/shared/start/gettargethash-default.c index 1647b01a66..28336b9f47 100644 --- a/bsps/shared/start/gettargethash-default.c +++ b/bsps/shared/start/gettargethash-default.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/mallocinitmulti.c b/bsps/shared/start/mallocinitmulti.c index ad04ea14ed..3d774ab65f 100644 --- a/bsps/shared/start/mallocinitmulti.c +++ b/bsps/shared/start/mallocinitmulti.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/mallocinitone.c b/bsps/shared/start/mallocinitone.c index 249f0b8e02..f590523ea1 100644 --- a/bsps/shared/start/mallocinitone.c +++ b/bsps/shared/start/mallocinitone.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/stackalloc.c b/bsps/shared/start/stackalloc.c index 1d2b0e6880..485753fad9 100644 --- a/bsps/shared/start/stackalloc.c +++ b/bsps/shared/start/stackalloc.c @@ -9,7 +9,7 @@ */ /* - * Copyright (c) 2009-2013 embedded brains GmbH. All rights reserved. + * Copyright (C) 2009, 2013 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/wkspaceinitmulti.c b/bsps/shared/start/wkspaceinitmulti.c index 2a0d0b5806..8ca34c1bc5 100644 --- a/bsps/shared/start/wkspaceinitmulti.c +++ b/bsps/shared/start/wkspaceinitmulti.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/start/wkspaceinitone.c b/bsps/shared/start/wkspaceinitone.c index 91d007d100..a93edad962 100644 --- a/bsps/shared/start/wkspaceinitone.c +++ b/bsps/shared/start/wkspaceinitone.c @@ -10,7 +10,7 @@ */ /* - * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2020 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/bsps/shared/xil/xil_cache.c b/bsps/shared/xil/arm/ARMv8/xil_cache.c index aef64b310a..aef64b310a 100644 --- a/bsps/shared/xil/xil_cache.c +++ b/bsps/shared/xil/arm/ARMv8/xil_cache.c diff --git a/bsps/shared/xil/arm/cortexr5/xil_cache.c b/bsps/shared/xil/arm/cortexr5/xil_cache.c new file mode 100644 index 0000000000..631d02f648 --- /dev/null +++ b/bsps/shared/xil/arm/cortexr5/xil_cache.c @@ -0,0 +1,561 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* +* @file xil_cache.c +* +* Contains required functions for the ARM cache functionality. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- ----------------------------------------------- +* 5.00 pkp 02/20/14 First release +* 6.2 mus 01/27/17 Updated to support IAR compiler +* 7.3 dp 06/25/20 Updated to support armclang compiler +* 7.7 sk 01/10/22 Update IRQ_FIQ_MASK macro from signed to unsigned +* to fix misra_c_2012_rule_10_4 violation. +* 7.7 sk 01/10/22 Typecast to fix wider essential type misra_c_2012_rule_10_7 +* violation. +* 7.7 mus 02/21/22 Existing note in cache API's says, "bottom 4 bits of input +* address are forced to 0 as per architecture". As cache line +* length is of 32 byte, bottom 5 bits of input address would +* be forced to 0. Updated note to have correct details. +* It fixes CR#1122561. +* </pre> +* +******************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xil_cache.h" +#include "xil_io.h" +#include "xpseudo_asm.h" +#include "xparameters.h" +#include "xreg_cortexr5.h" +#include "xil_exception.h" + + +/************************** Variable Definitions *****************************/ + +#define IRQ_FIQ_MASK 0xC0U /* Mask IRQ and FIQ interrupts in cpsr */ + +#if defined (__clang__) +extern s32 Image$$ARM_LIB_STACK$$Limit; +extern s32 Image$$ARM_UNDEF_STACK$$Base; +#elif defined (__GNUC__) +extern s32 _stack_end; +extern s32 __undef_stack; +#endif + +/****************************************************************************/ +/************************** Function Prototypes ******************************/ + +/****************************************************************************/ +/** +* @brief Enable the Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheEnable(void) +{ + register u32 CtrlReg; + + /* enable caches only if they are disabled */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + if ((CtrlReg & XREG_CP15_CONTROL_C_BIT)==0x00000000U) { + /* invalidate the Data cache */ + Xil_DCacheInvalidate(); + + /* enable the Data cache */ + CtrlReg |= (XREG_CP15_CONTROL_C_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + } +} + +/****************************************************************************/ +/** +* @brief Disable the Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheDisable(void) +{ + register u32 CtrlReg; + + /* clean and invalidate the Data cache */ + Xil_DCacheFlush(); + + /* disable the Data cache */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + + CtrlReg &= ~(XREG_CP15_CONTROL_C_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); +} + +/****************************************************************************/ +/** +* @brief Invalidate the entire Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheInvalidate(void) +{ + u32 currmask; + u32 stack_start,stack_end,stack_size; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + +#if defined (__clang__) + stack_end = (u32 )&Image$$ARM_LIB_STACK$$Limit; + stack_start = (u32 )&Image$$ARM_UNDEF_STACK$$Base; +#elif defined (__GNUC__) + stack_end = (u32 )&_stack_end; + stack_start = (u32 )&__undef_stack; +#endif + +#if defined(__GNUC__) || defined(__clang__) + stack_size = stack_start-stack_end; + + /* Flush stack memory to save return address */ + Xil_DCacheFlushRange(stack_end, stack_size); +#endif + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + + /*invalidate all D cache*/ + mtcp(XREG_CP15_INVAL_DC_ALL, 0); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate a Data cache line. If the byte specified by the +* address (adr) is cached by the data cache, the cacheline +* containing that byte is invalidated.If the cacheline is modified +* (dirty), the modified contents are lost and are NOT written +* to system memory before the line is invalidated. +* +* +* @param adr: 32bit address of the data to be flushed. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheInvalidateLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + mtcp(XREG_CP15_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F))); + + /* Wait for invalidate to complete */ + dsb(); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate the Data cache for the given address range. +* If the bytes specified by the address (adr) are cached by the +* Data cache,the cacheline containing that byte is invalidated. +* If the cacheline is modified (dirty), the modified contents are +* lost and are NOT written to system memory before the line is +* invalidated. +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of range to be invalidated in bytes. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheInvalidateRange(INTPTR adr, u32 len) +{ + const u32 cacheline = 32U; + u32 end; + u32 tempadr = adr; + u32 tempend; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0U) { + end = tempadr + len; + tempend = end; + /* Select L1 Data cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0U); + + if ((tempadr & (cacheline-1U)) != 0U) { + tempadr &= (~(cacheline - 1U)); + + Xil_DCacheFlushLine(tempadr); + } + if ((tempend & (cacheline-1U)) != 0U) { + tempend &= (~(cacheline - 1U)); + + Xil_DCacheFlushLine(tempend); + } + + while (tempadr < tempend) { + + /* Invalidate Data cache line */ + asm_inval_dc_line_mva_poc(tempadr); + + tempadr += cacheline; + } + } + + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the entire Data cache. +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheFlush(void) +{ + register u32 CsidReg, C7Reg; + u32 CacheSize, LineSize, NumWays; + u32 Way, WayIndex, Set, SetIndex, NumSet; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + /* Select cache level 0 and D cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + +#if defined (__GNUC__) + CsidReg = mfcp(XREG_CP15_CACHE_SIZE_ID); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_CACHE_SIZE_ID,CsidReg); +#endif + /* Determine Cache Size */ + + CacheSize = (CsidReg >> 13U) & 0x000001FFU; + CacheSize += 0x00000001U; + CacheSize *= (u32)128; /* to get number of bytes */ + + /* Number of Ways */ + NumWays = (CsidReg & 0x000003ffU) >> 3U; + NumWays += 0x00000001U; + + /* Get the cacheline size, way size, index size from csidr */ + LineSize = (CsidReg & 0x00000007U) + 0x00000004U; + + NumSet = CacheSize/NumWays; + NumSet /= (((u32)0x00000001U) << LineSize); + + Way = 0U; + Set = 0U; + + /* Invalidate all the cachelines */ + for (WayIndex = 0U; WayIndex < NumWays; WayIndex++) { + for (SetIndex = 0U; SetIndex < NumSet; SetIndex++) { + C7Reg = Way | Set; + /* Flush by Set/Way */ + asm_clean_inval_dc_line_sw(C7Reg); + + Set += (((u32)0x00000001U) << LineSize); + } + Set = 0U; + Way += 0x40000000U; + } + + /* Wait for flush to complete */ + dsb(); + mtcpsr(currmask); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush a Data cache line. If the byte specified by the address (adr) +* is cached by the Data cache, the cacheline containing that byte is +* invalidated. If the cacheline is modified (dirty), the entire +* contents of the cacheline are written to system memory before the +* line is invalidated. +* +* @param adr: 32bit address of the data to be flushed. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheFlushLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + + mtcp(XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC, (adr & (~0x1F))); + + /* Wait for flush to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Flush the Data cache for the given address range. +* If the bytes specified by the address (adr) are cached by the +* Data cache, the cacheline containing those bytes is invalidated.If +* the cacheline is modified (dirty), the written to system memory +* before the lines are invalidated. +* +* @param adr: 32bit start address of the range to be flushed. +* @param len: Length of the range to be flushed in bytes +* +* @return None. +* +****************************************************************************/ +void Xil_DCacheFlushRange(INTPTR adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + if (len != 0x00000000U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr &= ~(cacheline - 1U); + + while (LocalAddr < end) { + /* Flush Data cache line */ + asm_clean_inval_dc_line_mva_poc(LocalAddr); + + LocalAddr += cacheline; + } + } + dsb(); + mtcpsr(currmask); +} +/****************************************************************************/ +/** +* @brief Store a Data cache line. If the byte specified by the address +* (adr) is cached by the Data cache and the cacheline is modified +* (dirty), the entire contents of the cacheline are written to +* system memory.After the store completes, the cacheline is marked +* as unmodified (not dirty). +* +* @param adr: 32bit address of the data to be stored +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_DCacheStoreLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 0); + mtcp(XREG_CP15_CLEAN_DC_LINE_MVA_POC, (adr & (~0x1F))); + + /* Wait for store to complete */ + dsb(); + isb(); + + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Enable the instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheEnable(void) +{ + register u32 CtrlReg; + + /* enable caches only if they are disabled */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL, CtrlReg); +#endif + if ((CtrlReg & XREG_CP15_CONTROL_I_BIT)==0x00000000U) { + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0); + + /* enable the instruction cache */ + CtrlReg |= (XREG_CP15_CONTROL_I_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); + } +} + +/****************************************************************************/ +/** +* @brief Disable the instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheDisable(void) +{ + register u32 CtrlReg; + + dsb(); + + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0); + + /* disable the instruction cache */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + + CtrlReg &= ~(XREG_CP15_CONTROL_I_BIT); + + mtcp(XREG_CP15_SYS_CONTROL, CtrlReg); +} + +/****************************************************************************/ +/** +* @brief Invalidate the entire instruction cache. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheInvalidate(void) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1); + + /* invalidate the instruction cache */ + mtcp(XREG_CP15_INVAL_IC_POU, 0); + + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate an instruction cache line.If the instruction specified +* by the address is cached by the instruction cache, the +* cacheline containing that instruction is invalidated. +* +* @param adr: 32bit address of the instruction to be invalidated. +* +* @return None. +* +* @note The bottom 5 bits are set to 0, forced by architecture. +* +****************************************************************************/ +void Xil_ICacheInvalidateLine(INTPTR adr) +{ + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1); + mtcp(XREG_CP15_INVAL_IC_LINE_MVA_POU, (adr & (~0x1F))); + + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} + +/****************************************************************************/ +/** +* @brief Invalidate the instruction cache for the given address range. +* If the bytes specified by the address (adr) are cached by the +* Data cache, the cacheline containing that byte is invalidated. +* If the cachelineis modified (dirty), the modified contents are +* lost and are NOT written to system memory before the line is +* invalidated. +* +* @param adr: 32bit start address of the range to be invalidated. +* @param len: Length of the range to be invalidated in bytes. +* +* @return None. +* +****************************************************************************/ +void Xil_ICacheInvalidateRange(INTPTR adr, u32 len) +{ + u32 LocalAddr = adr; + const u32 cacheline = 32U; + u32 end; + u32 currmask; + + currmask = mfcpsr(); + mtcpsr(currmask | IRQ_FIQ_MASK); + if (len != 0x00000000U) { + /* Back the starting address up to the start of a cache line + * perform cache operations until adr+len + */ + end = LocalAddr + len; + LocalAddr = LocalAddr & ~(cacheline - 1U); + + /* Select cache L0 I-cache in CSSR */ + mtcp(XREG_CP15_CACHE_SIZE_SEL, 1U); + + while (LocalAddr < end) { + + /* Invalidate L1 I-cache line */ + asm_inval_ic_line_mva_pou(LocalAddr); + + LocalAddr += cacheline; + } + } + + /* Wait for invalidate to complete */ + dsb(); + mtcpsr(currmask); +} diff --git a/bsps/shared/xil/arm/cortexr5/xil_mpu.c b/bsps/shared/xil/arm/cortexr5/xil_mpu.c new file mode 100644 index 0000000000..85f8f7f8da --- /dev/null +++ b/bsps/shared/xil/arm/cortexr5/xil_mpu.c @@ -0,0 +1,645 @@ +/****************************************************************************** +* Copyright (c) 2014 - 2022 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ + +/*****************************************************************************/ +/** +* @file xil_mpu.c +* +* This file provides APIs for enabling/disabling MPU and setting the memory +* attributes for sections, in the MPU translation table. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver Who Date Changes +* ----- ---- -------- --------------------------------------------------- +* 5.00 pkp 02/10/14 Initial version +* 6.2 mus 01/27/17 Updated to support IAR compiler +* 6.4 asa 08/16/17 Added many APIs for MPU access to make MPU usage +* user-friendly. The APIs added are: Xil_UpdateMPUConfig, +* Xil_GetMPUConfig, Xil_GetNumOfFreeRegions, +* Xil_GetNextMPURegion, Xil_DisableMPURegionByRegNum, +* Xil_GetMPUFreeRegMask, Xil_SetMPURegionByRegNum, and +* Xil_InitializeExistingMPURegConfig. +* Added a new array of structure of type XMpuConfig to +* represent the MPU configuration table. +* 6.8 aru 07/02/18 Returned the pointer instead of address +* of that pointer in Xil_MemMap(). +* 7.5 asa 03/01/21 Ensure that Mpu_Config does not stay in .boot/.vector +* sections which generally should be executable code +* which can be allocated and not written. +* Mpu_Config array is populated during boot time, hence +* cannot be placed in .bss or .data section. Putting +* Mpu_Config in a new .bootdata section. +* 7.7 sk 01/10/22 Update int to u32 to fix misrac misra_c_2012_directive_4_6 +* violations. +* 7.7 sk 01/10/22 Typecast variables from signed to unsigned to fix +* misra_c_2012_rule_10_4 violation. +* 7.7 sk 01/10/22 Add explicit parentheses for region_size and region_size[0] +* to fix misra_c_2012_rule_12_1 violation. +* 7.7 sk 01/10/22 Remove unsigned sign to fix misra_c_2012_rule_10_3 violation. +* 7.7 sk 01/10/22 Modify if condition to fix misra_c_2012_rule_10_1 violation. +* 7.7 sk 01/10/22 Typecast to fix wider essential type misra_c_2012_rule_10_7 +* violation. +* 7.7 sk 01/10/22 Update conditional expression to fix misra_c_2012_rule_14_4 +* violation. +* 7.7 sk 01/10/22 Add braces for the if statement to make it a compound +* statement to fix misra_c_2012_rule_15_6 violation. +* </pre> +* +* +******************************************************************************/ + +/* + * Origin: https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/arm/cortexr5/xil_mpu.c + * __rtems__ changes: + * - un-include xdebug.h and add macro for xdbg_printf + * - relocate XMpu_Config + * - form Xilinx link script section(".bootdata") + * - to RTEMS link script section(".bsp_start_data") + */ + +/***************************** Include Files *********************************/ + +#include "xil_cache.h" +#include "xpseudo_asm.h" +#include "xil_types.h" +#include "xil_mpu.h" +#ifndef __rtems__ +#include "xdebug.h" +#else +#define xdbg_printf(...) +#endif +#include "xstatus.h" +/***************** Macros (Inline Functions) Definitions *********************/ + +/**************************** Type Definitions *******************************/ + +/************************** Constant Definitions *****************************/ +#define MPU_REGION_SIZE_MIN 0x20 +/************************** Variable Definitions *****************************/ + +static const struct { + u64 size; + u32 encoding; +}region_size[] = { + { 0x20, REGION_32B }, + { 0x40, REGION_64B }, + { 0x80, REGION_128B }, + { 0x100, REGION_256B }, + { 0x200, REGION_512B }, + { 0x400, REGION_1K }, + { 0x800, REGION_2K }, + { 0x1000, REGION_4K }, + { 0x2000, REGION_8K }, + { 0x4000, REGION_16K }, + { 0x8000, REGION_32K }, + { 0x10000, REGION_64K }, + { 0x20000, REGION_128K }, + { 0x40000, REGION_256K }, + { 0x80000, REGION_512K }, + { 0x100000, REGION_1M }, + { 0x200000, REGION_2M }, + { 0x400000, REGION_4M }, + { 0x800000, REGION_8M }, + { 0x1000000, REGION_16M }, + { 0x2000000, REGION_32M }, + { 0x4000000, REGION_64M }, + { 0x8000000, REGION_128M }, + { 0x10000000, REGION_256M }, + { 0x20000000, REGION_512M }, + { 0x40000000, REGION_1G }, + { 0x80000000, REGION_2G }, + { 0x100000000, REGION_4G }, +}; + +#ifndef __rtems__ +#if defined (__GNUC__) +XMpu_Config Mpu_Config __attribute__((section(".bootdata"))); +#elif defined (__ICCARM__) +#pragma default_function_attributes = @ ".bootdata" +XMpu_Config Mpu_Config; +#endif +#else +XMpu_Config Mpu_Config __attribute__((section(".bsp_start_data"))); +#endif + +/************************** Function Prototypes ******************************/ +void Xil_InitializeExistingMPURegConfig(void); +/*****************************************************************************/ +/** +* @brief This function sets the memory attributes for a section covering +* 1MB, of memory in the translation table. +* +* @param addr: 32-bit address for which memory attributes need to be set. +* @param attrib: Attribute for the given memory region. +* @return None. +* +* +******************************************************************************/ +void Xil_SetTlbAttributes(INTPTR addr, u32 attrib) +{ + INTPTR Localaddr = addr; + Localaddr &= (INTPTR)(~(0xFFFFFU)); + /* Setting the MPU region with given attribute with 1MB size */ + Xil_SetMPURegion(Localaddr, 0x100000, attrib); +} + +/*****************************************************************************/ +/** +* @brief Set the memory attributes for a section of memory in the +* translation table. +* +* @param addr: 32-bit address for which memory attributes need to be set.. +* @param size: size is the size of the region. +* @param attrib: Attribute for the given memory region. +* @return None. +* +* +******************************************************************************/ +u32 Xil_SetMPURegion(INTPTR addr, u64 size, u32 attrib) +{ + u32 Regionsize = 0; + INTPTR Localaddr = addr; + u32 NextAvailableMemRegion; + u32 i; + + NextAvailableMemRegion = Xil_GetNextMPURegion(); + if (NextAvailableMemRegion == 0xFFU) { + xdbg_printf(DEBUG, "No regions available\r\n"); + return XST_FAILURE; + } + + Xil_DCacheFlush(); + Xil_ICacheInvalidate(); + + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,NextAvailableMemRegion); + isb(); + + /* Lookup the size. */ + for (i = 0; i < (sizeof (region_size) / sizeof (region_size[0])); i++) { + if (size <= region_size[i].size) { + Regionsize = region_size[i].encoding; + break; + } + } + + Localaddr &= (INTPTR)(~(region_size[i].size - 1U)); + + Regionsize <<= 1; + Regionsize |= REGION_EN; + dsb(); + mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr); /* Set base address of a region */ + mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib); /* Set the control attribute */ + mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize); /* set the region size and enable it*/ + dsb(); + isb(); + Xil_UpdateMPUConfig(NextAvailableMemRegion, Localaddr, Regionsize, attrib); + return XST_SUCCESS; +} +/*****************************************************************************/ +/** +* @brief Enable MPU for Cortex R5 processor. This function invalidates I +* cache and flush the D Caches, and then enables the MPU. +* +* @return None. +* +******************************************************************************/ +void Xil_EnableMPU(void) +{ + u32 CtrlReg, Reg; + s32 DCacheStatus=0, ICacheStatus=0; + /* enable caches only if they are disabled */ +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + if ((CtrlReg & XREG_CP15_CONTROL_C_BIT) != 0x00000000U) { + DCacheStatus=1; + } + if ((CtrlReg & XREG_CP15_CONTROL_I_BIT) != 0x00000000U) { + ICacheStatus=1; + } + + if(DCacheStatus != 0) { + Xil_DCacheDisable(); + } + if(ICacheStatus != 0){ + Xil_ICacheDisable(); + } +#if defined (__GNUC__) + Reg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,Reg); +#endif + Reg |= 0x00000001U; + dsb(); + mtcp(XREG_CP15_SYS_CONTROL, Reg); + isb(); + /* enable caches only if they are disabled in routine*/ + if(DCacheStatus != 0) { + Xil_DCacheEnable(); + } + if(ICacheStatus != 0) { + Xil_ICacheEnable(); + } +} + +/*****************************************************************************/ +/** +* @brief Disable MPU for Cortex R5 processors. This function invalidates I +* cache and flush the D Caches, and then disabes the MPU. +* +* @return None. +* +******************************************************************************/ +void Xil_DisableMPU(void) +{ + u32 CtrlReg, Reg; + s32 DCacheStatus=0, ICacheStatus=0; + /* enable caches only if they are disabled */ + +#if defined (__GNUC__) + CtrlReg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,CtrlReg); +#endif + if ((CtrlReg & XREG_CP15_CONTROL_C_BIT) != 0x00000000U) { + DCacheStatus=1; + } + if ((CtrlReg & XREG_CP15_CONTROL_I_BIT) != 0x00000000U) { + ICacheStatus=1; + } + + if(DCacheStatus != 0) { + Xil_DCacheDisable(); + } + if(ICacheStatus != 0){ + Xil_ICacheDisable(); + } + + mtcp(XREG_CP15_INVAL_BRANCH_ARRAY, 0); +#if defined (__GNUC__) + Reg = mfcp(XREG_CP15_SYS_CONTROL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_SYS_CONTROL,Reg); +#endif + Reg &= ~(0x00000001U); + dsb(); + mtcp(XREG_CP15_SYS_CONTROL, Reg); + isb(); + /* enable caches only if they are disabled in routine*/ + if(DCacheStatus != 0) { + Xil_DCacheEnable(); + } + if(ICacheStatus != 0) { + Xil_ICacheEnable(); + } +} + +/*****************************************************************************/ +/** +* @brief Update the MPU configuration for the requested region number in +* the global MPU configuration table. +* +* @param reg_num: The requested region number to be updated information for. +* @param address: 32 bit address for start of the region. +* @param size: Requested size of the region. +* @param attrib: Attribute for the corresponding region. +* @return XST_FAILURE: When the requested region number if 16 or more. +* XST_SUCCESS: When the MPU configuration table is updated. +* +* +******************************************************************************/ +u32 Xil_UpdateMPUConfig(u32 reg_num, INTPTR address, u32 size, u32 attrib) +{ + u32 ReturnVal = XST_SUCCESS; + u32 Tempsize = size; + u32 Index; + + if (reg_num >= MAX_POSSIBLE_MPU_REGS) { + xdbg_printf(DEBUG, "Invalid region number\r\n"); + ReturnVal = XST_FAILURE; + goto exit; + } + + if ((size & REGION_EN) != 0) { + Mpu_Config[reg_num].RegionStatus = MPU_REG_ENABLED; + Mpu_Config[reg_num].BaseAddress = address; + Tempsize &= (~REGION_EN); + Tempsize >>= 1; + /* Lookup the size. */ + for (Index = 0; Index < + (sizeof (region_size) / sizeof (region_size[0])); Index++) { + if (Tempsize <= region_size[Index].encoding) { + Mpu_Config[reg_num].Size = region_size[Index].size; + break; + } + } + Mpu_Config[reg_num].Attribute = attrib; + } else { + Mpu_Config[reg_num].RegionStatus = 0U; + Mpu_Config[reg_num].BaseAddress = 0; + Mpu_Config[reg_num].Size = 0U; + Mpu_Config[reg_num].Attribute = 0U; + } + +exit: + return ReturnVal; +} + +/*****************************************************************************/ +/** +* @brief The MPU configuration table is passed to the caller. +* +* @param mpuconfig: This is of type XMpu_Config which is an array of +* 16 entries of type structure representing the MPU config table +* @return none +* +* +******************************************************************************/ +void Xil_GetMPUConfig (XMpu_Config mpuconfig) { + u32 Index = 0U; + + while (Index < MAX_POSSIBLE_MPU_REGS) { + mpuconfig[Index].RegionStatus = Mpu_Config[Index].RegionStatus; + mpuconfig[Index].BaseAddress = Mpu_Config[Index].BaseAddress; + mpuconfig[Index].Attribute = Mpu_Config[Index].Attribute; + mpuconfig[Index].Size = Mpu_Config[Index].Size; + Index++; + } +} + +/*****************************************************************************/ +/** +* @brief Returns the total number of free MPU regions available. +* +* @return Number of free regions available to users +* +* +******************************************************************************/ +u32 Xil_GetNumOfFreeRegions (void) { + u32 Index = 0U; + u32 NumofFreeRegs = 0U; + + while (Index < MAX_POSSIBLE_MPU_REGS) { + if (MPU_REG_DISABLED == Mpu_Config[Index].RegionStatus) { + NumofFreeRegs++; + } + Index++; + } + return NumofFreeRegs; +} + +/*****************************************************************************/ +/** +* @brief Returns the total number of free MPU regions available in the form +* of a mask. A bit of 1 in the returned 16 bit value represents the +* corresponding region number to be available. +* For example, if this function returns 0xC0000, this would mean, the +* regions 14 and 15 are available to users. +* +* @return The free region mask as a 16 bit value +* +* +******************************************************************************/ +u16 Xil_GetMPUFreeRegMask (void) { + u32 Index = 0U; + u16 FreeRegMask = 0U; + + while (Index < MAX_POSSIBLE_MPU_REGS) { + if (MPU_REG_DISABLED == Mpu_Config[Index].RegionStatus) { + FreeRegMask |= ((u16)1U << Index); + } + Index++; + } + return FreeRegMask; +} + +/*****************************************************************************/ +/** +* @brief Disables the corresponding region number as passed by the user. +* +* @param reg_num: The region number to be disabled +* @return XST_SUCCESS: If the region could be disabled successfully +* XST_FAILURE: If the requested region number is 16 or more. +* +* +******************************************************************************/ +u32 Xil_DisableMPURegionByRegNum (u32 reg_num) { + u32 Temp = 0U; + u32 ReturnVal = XST_FAILURE; + + if (reg_num >= 16U) { + xdbg_printf(DEBUG, "Invalid region number\r\n"); + goto exit1; + } + Xil_DCacheFlush(); + Xil_ICacheInvalidate(); + + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num); +#if defined (__GNUC__) + Temp = mfcp(XREG_CP15_MPU_REG_SIZE_EN); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_MPU_REG_SIZE_EN,Temp); +#endif + Temp &= (~REGION_EN); + dsb(); + mtcp(XREG_CP15_MPU_REG_SIZE_EN,Temp); + dsb(); + isb(); + Xil_UpdateMPUConfig(reg_num, 0, 0U, 0U); + ReturnVal = XST_SUCCESS; + +exit1: + return ReturnVal; +} + +/*****************************************************************************/ +/** +* @brief Enables the corresponding region number as passed by the user. +* +* @param reg_num: The region number to be enabled +* @param addr: 32 bit address for start of the region. +* @param size: Requested size of the region. +* @param attrib: Attribute for the corresponding region. +* @return XST_SUCCESS: If the region could be created successfully +* XST_FAILURE: If the requested region number is 16 or more. +* +* +******************************************************************************/ +u32 Xil_SetMPURegionByRegNum (u32 reg_num, INTPTR addr, u64 size, u32 attrib) +{ + u32 ReturnVal = XST_SUCCESS; + INTPTR Localaddr = addr; + u32 Regionsize = 0; + u32 Index; + + if (reg_num >= 16U) { + xdbg_printf(DEBUG, "Invalid region number\r\n"); + ReturnVal = XST_FAILURE; + goto exit2; + } + + if (Mpu_Config[reg_num].RegionStatus == MPU_REG_ENABLED) { + xdbg_printf(DEBUG, "Region already enabled\r\n"); + ReturnVal = XST_FAILURE; + goto exit2; + } + + Xil_DCacheFlush(); + Xil_ICacheInvalidate(); + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,reg_num); + isb(); + + /* Lookup the size. */ + for (Index = 0; Index < + (sizeof (region_size) / sizeof (region_size[0])); Index++) { + if (size <= region_size[Index].size) { + Regionsize = region_size[Index].encoding; + break; + } + } + + Localaddr &= (INTPTR)(~(region_size[Index].size - 1U)); + Regionsize <<= 1; + Regionsize |= REGION_EN; + dsb(); + mtcp(XREG_CP15_MPU_REG_BASEADDR, Localaddr); + mtcp(XREG_CP15_MPU_REG_ACCESS_CTRL, attrib); + mtcp(XREG_CP15_MPU_REG_SIZE_EN, Regionsize); + dsb(); + isb(); + Xil_UpdateMPUConfig(reg_num, Localaddr, Regionsize, attrib); +exit2: + return ReturnVal; + +} + +/*****************************************************************************/ +/** +* @brief Initializes the MPU configuration table that are setup in the +* R5 boot code in the Init_Mpu function called before C main. +* +* @return none +* +* +******************************************************************************/ +void Xil_InitializeExistingMPURegConfig(void) +{ + u32 Index = 0U; + u32 Index1 = 0U; + u32 MPURegSize; + INTPTR MPURegBA; + u32 MPURegAttrib; + u32 Tempsize; + + while (Index < MAX_POSSIBLE_MPU_REGS) { + mtcp(XREG_CP15_MPU_MEMORY_REG_NUMBER,Index); +#if defined (__GNUC__) + MPURegSize = mfcp(XREG_CP15_MPU_REG_SIZE_EN); + MPURegBA = mfcp(XREG_CP15_MPU_REG_BASEADDR); + MPURegAttrib = mfcp(XREG_CP15_MPU_REG_ACCESS_CTRL); +#elif defined (__ICCARM__) + mfcp(XREG_CP15_MPU_REG_SIZE_EN,MPURegSize); + mfcp(XREG_CP15_MPU_REG_BASEADDR, MPURegBA); + mfcp(XREG_CP15_MPU_REG_ACCESS_CTRL, MPURegAttrib); +#endif + if ((MPURegSize & REGION_EN) != 0) { + Mpu_Config[Index].RegionStatus = MPU_REG_ENABLED; + Mpu_Config[Index].BaseAddress = MPURegBA; + Mpu_Config[Index].Attribute = MPURegAttrib; + Tempsize = MPURegSize & (~REGION_EN); + Tempsize >>= 1; + for (Index1 = 0; Index1 < + (sizeof (region_size) / sizeof (region_size[0])); Index1++) { + if (Tempsize <= region_size[Index1].encoding) { + Mpu_Config[Index].Size = region_size[Index1].size; + break; + } + } + } + Index++; + } +} + +/*****************************************************************************/ +/** +* @brief Returns the next available free MPU region +* +* @return The free MPU region available +* +* +******************************************************************************/ +u32 Xil_GetNextMPURegion(void) +{ + u32 Index = 0U; + u32 NextAvailableReg = 0xFF; + while (Index < MAX_POSSIBLE_MPU_REGS) { + if (Mpu_Config[Index].RegionStatus != MPU_REG_ENABLED) { + NextAvailableReg = Index; + break; + } + Index++; + } + return NextAvailableReg; +} + +#ifdef __GNUC__ +#define u32overflow(a, b) ({typeof(a) s; __builtin_uadd_overflow(a, b, &s); }) +#else +#define u32overflow(a, b) ((a) > ((a) + (b))) +#endif /* __GNUC__ */ + +/*****************************************************************************/ +/** +* @brief Memory mapping for Cortex-R5F. If successful, the mapped +* region will include all of the memory requested, but may +* include more. Specifically, it will be a power of 2 in +* size, aligned on a boundary of that size. +* +* @param Physaddr is base physical address at which to start mapping. +* NULL in Physaddr masks possible mapping errors. +* @param size of region to be mapped. +* @param flags used to set translation table. +* +* @return Physaddr on success, NULL on error. Ambiguous if Physaddr==NULL +* +* @cond Xil_MemMap_internal +* @note: u32overflow() is defined for readability and (for __GNUC__) to +* - force the type of the check to be the same as the first argument +* - hide the otherwise unused third argument of the builtin +* - improve safety by choosing the explicit _uadd_ version. +* Consider __builtin_add_overflow_p() when available. +* Use an alternative (less optimal?) for compilers w/o the builtin. +* @endcond +******************************************************************************/ +void *Xil_MemMap(UINTPTR Physaddr, size_t size, u32 flags) +{ + size_t Regionsize = MPU_REGION_SIZE_MIN; + UINTPTR Basephysaddr = 0, end = Physaddr + size; + + if (flags == 0U) { + return (void *)Physaddr; + } + if (u32overflow(Physaddr, size)) { + return NULL; + } + for ( ; Regionsize != 0U; Regionsize <<= 1) { + if (Regionsize >= size) { + Basephysaddr = Physaddr & ~(Regionsize - 1U); + if (u32overflow(Basephysaddr, Regionsize)) { + break; + } + if ((Basephysaddr + Regionsize) >= end) { + return ((Xil_SetMPURegion(Basephysaddr, + Regionsize, flags) == XST_SUCCESS) ? + (void *)Physaddr : NULL); + } + } + } + return NULL; +} |