diff options
Diffstat (limited to 'bsps/powerpc/qoriq')
-rw-r--r-- | bsps/powerpc/qoriq/headers.am | 24 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/asm/epapr_hcalls.h | 573 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/asm/fsl_hcalls.h | 653 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/bsp.h | 128 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/bsp/intercom.h | 125 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/bsp/irq.h | 401 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/bsp/mmu.h | 101 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/bsp/qoriq.h | 559 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/bsp/tsec-config.h | 36 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/bsp/uart-bridge.h | 72 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/tm27.h | 96 | ||||
-rw-r--r-- | bsps/powerpc/qoriq/include/uapi/asm/epapr_hcalls.h | 98 |
12 files changed, 2866 insertions, 0 deletions
diff --git a/bsps/powerpc/qoriq/headers.am b/bsps/powerpc/qoriq/headers.am new file mode 100644 index 0000000000..9d23263d43 --- /dev/null +++ b/bsps/powerpc/qoriq/headers.am @@ -0,0 +1,24 @@ +## This file was generated by "./boostrap -H". + +include_HEADERS = +include_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/bsp.h +include_HEADERS += include/bspopts.h +include_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/tm27.h + +include_asmdir = $(includedir)/asm +include_asm_HEADERS = +include_asm_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/asm/epapr_hcalls.h +include_asm_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/asm/fsl_hcalls.h + +include_bspdir = $(includedir)/bsp +include_bsp_HEADERS = +include_bsp_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/bsp/intercom.h +include_bsp_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/bsp/irq.h +include_bsp_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/bsp/mmu.h +include_bsp_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/bsp/qoriq.h +include_bsp_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/bsp/tsec-config.h +include_bsp_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/bsp/uart-bridge.h + +include_uapi_asmdir = $(includedir)/uapi/asm +include_uapi_asm_HEADERS = +include_uapi_asm_HEADERS += ../../../../../../bsps/powerpc/qoriq/include/uapi/asm/epapr_hcalls.h diff --git a/bsps/powerpc/qoriq/include/asm/epapr_hcalls.h b/bsps/powerpc/qoriq/include/asm/epapr_hcalls.h new file mode 100644 index 0000000000..3d87cca611 --- /dev/null +++ b/bsps/powerpc/qoriq/include/asm/epapr_hcalls.h @@ -0,0 +1,573 @@ +/* + * ePAPR hcall interface + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + * + * Author: Timur Tabi <timur@freescale.com> + * + * This file is provided under a dual BSD/GPL license. When using or + * redistributing this file, you may do so under either license. + * + * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +/* A "hypercall" is an "sc 1" instruction. This header file file provides C + * wrapper functions for the ePAPR hypervisor interface. It is inteded + * for use by Linux device drivers and other operating systems. + * + * The hypercalls are implemented as inline assembly, rather than assembly + * language functions in a .S file, for optimization. It allows + * the caller to issue the hypercall instruction directly, improving both + * performance and memory footprint. + */ + +#ifndef _EPAPR_HCALLS_H +#define _EPAPR_HCALLS_H + +#include <uapi/asm/epapr_hcalls.h> + +#ifndef __ASSEMBLY__ +#include <sys/endian.h> + +/* + * Hypercall register clobber list + * + * These macros are used to define the list of clobbered registers during a + * hypercall. Technically, registers r0 and r3-r12 are always clobbered, + * but the gcc inline assembly syntax does not allow us to specify registers + * on the clobber list that are also on the input/output list. Therefore, + * the lists of clobbered registers depends on the number of register + * parmeters ("+r" and "=r") passed to the hypercall. + * + * Each assembly block should use one of the HCALL_CLOBBERSx macros. As a + * general rule, 'x' is the number of parameters passed to the assembly + * block *except* for r11. + * + * If you're not sure, just use the smallest value of 'x' that does not + * generate a compilation error. Because these are static inline functions, + * the compiler will only check the clobber list for a function if you + * compile code that calls that function. + * + * r3 and r11 are not included in any clobbers list because they are always + * listed as output registers. + * + * XER, CTR, and LR are currently listed as clobbers because it's uncertain + * whether they will be clobbered. + * + * Note that r11 can be used as an output parameter. + * + * The "memory" clobber is only necessary for hcalls where the Hypervisor + * will read or write guest memory. However, we add it to all hcalls because + * the impact is minimal, and we want to ensure that it's present for the + * hcalls that need it. +*/ + +/* List of common clobbered registers. Do not use this macro. */ +#define EV_HCALL_CLOBBERS "r0", "r12", "xer", "ctr", "lr", "cc", "memory" + +#define EV_HCALL_CLOBBERS8 EV_HCALL_CLOBBERS +#define EV_HCALL_CLOBBERS7 EV_HCALL_CLOBBERS8, "r10" +#define EV_HCALL_CLOBBERS6 EV_HCALL_CLOBBERS7, "r9" +#define EV_HCALL_CLOBBERS5 EV_HCALL_CLOBBERS6, "r8" +#define EV_HCALL_CLOBBERS4 EV_HCALL_CLOBBERS5, "r7" +#define EV_HCALL_CLOBBERS3 EV_HCALL_CLOBBERS4, "r6" +#define EV_HCALL_CLOBBERS2 EV_HCALL_CLOBBERS3, "r5" +#define EV_HCALL_CLOBBERS1 EV_HCALL_CLOBBERS2, "r4" + +extern bool epapr_paravirt_enabled; +extern uint32_t epapr_hypercall_start[]; + +#ifdef CONFIG_EPAPR_PARAVIRT +int __init epapr_paravirt_early_init(void); +#else +static inline int epapr_paravirt_early_init(void) { return 0; } +#endif + +/* + * We use "uintptr_t" to define a register because it's guaranteed to be a + * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit + * platform. + * + * All registers are either input/output or output only. Registers that are + * initialized before making the hypercall are input/output. All + * input/output registers are represented with "+r". Output-only registers + * are represented with "=r". Do not specify any unused registers. The + * clobber list will tell the compiler that the hypercall modifies those + * registers, which is good enough. + */ + +/** + * ev_int_set_config - configure the specified interrupt + * @interrupt: the interrupt number + * @config: configuration for this interrupt + * @priority: interrupt priority + * @destination: destination CPU number + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_int_set_config(unsigned int interrupt, + uint32_t config, unsigned int priority, uint32_t destination) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + register uintptr_t r6 __asm__("r6"); + + r11 = EV_HCALL_TOKEN(EV_INT_SET_CONFIG); + r3 = interrupt; + r4 = config; + r5 = priority; + r6 = destination; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6) + : : EV_HCALL_CLOBBERS4 + ); + + return r3; +} + +/** + * ev_int_get_config - return the config of the specified interrupt + * @interrupt: the interrupt number + * @config: returned configuration for this interrupt + * @priority: returned interrupt priority + * @destination: returned destination CPU number + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_int_get_config(unsigned int interrupt, + uint32_t *config, unsigned int *priority, uint32_t *destination) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + register uintptr_t r6 __asm__("r6"); + + r11 = EV_HCALL_TOKEN(EV_INT_GET_CONFIG); + r3 = interrupt; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5), "=r" (r6) + : : EV_HCALL_CLOBBERS4 + ); + + *config = r4; + *priority = r5; + *destination = r6; + + return r3; +} + +/** + * ev_int_set_mask - sets the mask for the specified interrupt source + * @interrupt: the interrupt number + * @mask: 0=enable interrupts, 1=disable interrupts + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_int_set_mask(unsigned int interrupt, + unsigned int mask) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + + r11 = EV_HCALL_TOKEN(EV_INT_SET_MASK); + r3 = interrupt; + r4 = mask; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "+r" (r4) + : : EV_HCALL_CLOBBERS2 + ); + + return r3; +} + +/** + * ev_int_get_mask - returns the mask for the specified interrupt source + * @interrupt: the interrupt number + * @mask: returned mask for this interrupt (0=enabled, 1=disabled) + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_int_get_mask(unsigned int interrupt, + unsigned int *mask) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + + r11 = EV_HCALL_TOKEN(EV_INT_GET_MASK); + r3 = interrupt; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "=r" (r4) + : : EV_HCALL_CLOBBERS2 + ); + + *mask = r4; + + return r3; +} + +/** + * ev_int_eoi - signal the end of interrupt processing + * @interrupt: the interrupt number + * + * This function signals the end of processing for the the specified + * interrupt, which must be the interrupt currently in service. By + * definition, this is also the highest-priority interrupt. + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_int_eoi(unsigned int interrupt) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = EV_HCALL_TOKEN(EV_INT_EOI); + r3 = interrupt; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + +/** + * ev_byte_channel_send - send characters to a byte stream + * @handle: byte stream handle + * @count: (input) num of chars to send, (output) num chars sent + * @buffer: pointer to a 16-byte buffer + * + * @buffer must be at least 16 bytes long, because all 16 bytes will be + * read from memory into registers, even if count < 16. + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_byte_channel_send(unsigned int handle, + unsigned int *count, const char buffer[EV_BYTE_CHANNEL_MAX_BYTES]) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + register uintptr_t r6 __asm__("r6"); + register uintptr_t r7 __asm__("r7"); + register uintptr_t r8 __asm__("r8"); + const uint32_t *p = (const uint32_t *) buffer; + + r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_SEND); + r3 = handle; + r4 = *count; + r5 = be32toh(p[0]); + r6 = be32toh(p[1]); + r7 = be32toh(p[2]); + r8 = be32toh(p[3]); + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), + "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), "+r" (r8) + : : EV_HCALL_CLOBBERS6 + ); + + *count = r4; + + return r3; +} + +/** + * ev_byte_channel_receive - fetch characters from a byte channel + * @handle: byte channel handle + * @count: (input) max num of chars to receive, (output) num chars received + * @buffer: pointer to a 16-byte buffer + * + * The size of @buffer must be at least 16 bytes, even if you request fewer + * than 16 characters, because we always write 16 bytes to @buffer. This is + * for performance reasons. + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_byte_channel_receive(unsigned int handle, + unsigned int *count, char buffer[EV_BYTE_CHANNEL_MAX_BYTES]) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + register uintptr_t r6 __asm__("r6"); + register uintptr_t r7 __asm__("r7"); + register uintptr_t r8 __asm__("r8"); + uint32_t *p = (uint32_t *) buffer; + + r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_RECEIVE); + r3 = handle; + r4 = *count; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "+r" (r4), + "=r" (r5), "=r" (r6), "=r" (r7), "=r" (r8) + : : EV_HCALL_CLOBBERS6 + ); + + *count = r4; + p[0] = htobe32(r5); + p[1] = htobe32(r6); + p[2] = htobe32(r7); + p[3] = htobe32(r8); + + return r3; +} + +/** + * ev_byte_channel_poll - returns the status of the byte channel buffers + * @handle: byte channel handle + * @rx_count: returned count of bytes in receive queue + * @tx_count: returned count of free space in transmit queue + * + * This function reports the amount of data in the receive queue (i.e. the + * number of bytes you can read), and the amount of free space in the transmit + * queue (i.e. the number of bytes you can write). + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_byte_channel_poll(unsigned int handle, + unsigned int *rx_count, unsigned int *tx_count) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + + r11 = EV_HCALL_TOKEN(EV_BYTE_CHANNEL_POLL); + r3 = handle; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "=r" (r4), "=r" (r5) + : : EV_HCALL_CLOBBERS3 + ); + + *rx_count = r4; + *tx_count = r5; + + return r3; +} + +/** + * ev_int_iack - acknowledge an interrupt + * @handle: handle to the target interrupt controller + * @vector: returned interrupt vector + * + * If handle is zero, the function returns the next interrupt source + * number to be handled irrespective of the hierarchy or cascading + * of interrupt controllers. If non-zero, specifies a handle to the + * interrupt controller that is the target of the acknowledge. + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_int_iack(unsigned int handle, + unsigned int *vector) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + + r11 = EV_HCALL_TOKEN(EV_INT_IACK); + r3 = handle; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "=r" (r4) + : : EV_HCALL_CLOBBERS2 + ); + + *vector = r4; + + return r3; +} + +/** + * ev_doorbell_send - send a doorbell to another partition + * @handle: doorbell send handle + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_doorbell_send(unsigned int handle) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = EV_HCALL_TOKEN(EV_DOORBELL_SEND); + r3 = handle; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + +/** + * ev_idle -- wait for next interrupt on this core + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int ev_idle(void) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = EV_HCALL_TOKEN(EV_IDLE); + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "=r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + +#ifdef CONFIG_EPAPR_PARAVIRT +static inline unsigned long epapr_hypercall(unsigned long *in, + unsigned long *out, + unsigned long nr) +{ + unsigned long register r0 asm("r0"); + unsigned long register r3 asm("r3") = in[0]; + unsigned long register r4 asm("r4") = in[1]; + unsigned long register r5 asm("r5") = in[2]; + unsigned long register r6 asm("r6") = in[3]; + unsigned long register r7 asm("r7") = in[4]; + unsigned long register r8 asm("r8") = in[5]; + unsigned long register r9 asm("r9") = in[6]; + unsigned long register r10 asm("r10") = in[7]; + unsigned long register r11 asm("r11") = nr; + unsigned long register r12 asm("r12"); + + asm volatile("bl epapr_hypercall_start" + : "=r"(r0), "=r"(r3), "=r"(r4), "=r"(r5), "=r"(r6), + "=r"(r7), "=r"(r8), "=r"(r9), "=r"(r10), "=r"(r11), + "=r"(r12) + : "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7), "r"(r8), + "r"(r9), "r"(r10), "r"(r11) + : "memory", "cc", "xer", "ctr", "lr"); + + out[0] = r4; + out[1] = r5; + out[2] = r6; + out[3] = r7; + out[4] = r8; + out[5] = r9; + out[6] = r10; + out[7] = r11; + + return r3; +} +#else +static unsigned long epapr_hypercall(unsigned long *in, + unsigned long *out, + unsigned long nr) +{ + return EV_UNIMPLEMENTED; +} +#endif + +static inline long epapr_hypercall0_1(unsigned int nr, unsigned long *r2) +{ + unsigned long in[8]; + unsigned long out[8]; + unsigned long r; + + r = epapr_hypercall(in, out, nr); + *r2 = out[0]; + + return r; +} + +static inline long epapr_hypercall0(unsigned int nr) +{ + unsigned long in[8]; + unsigned long out[8]; + + return epapr_hypercall(in, out, nr); +} + +static inline long epapr_hypercall1(unsigned int nr, unsigned long p1) +{ + unsigned long in[8]; + unsigned long out[8]; + + in[0] = p1; + return epapr_hypercall(in, out, nr); +} + +static inline long epapr_hypercall2(unsigned int nr, unsigned long p1, + unsigned long p2) +{ + unsigned long in[8]; + unsigned long out[8]; + + in[0] = p1; + in[1] = p2; + return epapr_hypercall(in, out, nr); +} + +static inline long epapr_hypercall3(unsigned int nr, unsigned long p1, + unsigned long p2, unsigned long p3) +{ + unsigned long in[8]; + unsigned long out[8]; + + in[0] = p1; + in[1] = p2; + in[2] = p3; + return epapr_hypercall(in, out, nr); +} + +static inline long epapr_hypercall4(unsigned int nr, unsigned long p1, + unsigned long p2, unsigned long p3, + unsigned long p4) +{ + unsigned long in[8]; + unsigned long out[8]; + + in[0] = p1; + in[1] = p2; + in[2] = p3; + in[3] = p4; + return epapr_hypercall(in, out, nr); +} +#endif /* !__ASSEMBLY__ */ +#endif /* _EPAPR_HCALLS_H */ diff --git a/bsps/powerpc/qoriq/include/asm/fsl_hcalls.h b/bsps/powerpc/qoriq/include/asm/fsl_hcalls.h new file mode 100644 index 0000000000..ba76c132aa --- /dev/null +++ b/bsps/powerpc/qoriq/include/asm/fsl_hcalls.h @@ -0,0 +1,653 @@ +/* + * Freescale hypervisor call interface + * + * Copyright 2008-2010 Freescale Semiconductor, Inc. + * + * Author: Timur Tabi <timur@freescale.com> + * + * This file is provided under a dual BSD/GPL license. When using or + * redistributing this file, you may do so under either license. + * + * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef _FSL_HCALLS_H +#define _FSL_HCALLS_H + +#include <stdint.h> +#include <asm/epapr_hcalls.h> + +#define FH_API_VERSION 1 + +#define FH_ERR_GET_INFO 1 +#define FH_PARTITION_GET_DTPROP 2 +#define FH_PARTITION_SET_DTPROP 3 +#define FH_PARTITION_RESTART 4 +#define FH_PARTITION_GET_STATUS 5 +#define FH_PARTITION_START 6 +#define FH_PARTITION_STOP 7 +#define FH_PARTITION_MEMCPY 8 +#define FH_DMA_ENABLE 9 +#define FH_DMA_DISABLE 10 +#define FH_SEND_NMI 11 +#define FH_VMPIC_GET_MSIR 12 +#define FH_SYSTEM_RESET 13 +#define FH_GET_CORE_STATE 14 +#define FH_ENTER_NAP 15 +#define FH_EXIT_NAP 16 +#define FH_CLAIM_DEVICE 17 +#define FH_PARTITION_STOP_DMA 18 + +/* vendor ID: Freescale Semiconductor */ +#define FH_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_FSL_VENDOR_ID, num) + +/* + * We use "uintptr_t" to define a register because it's guaranteed to be a + * 32-bit integer on a 32-bit platform, and a 64-bit integer on a 64-bit + * platform. + * + * All registers are either input/output or output only. Registers that are + * initialized before making the hypercall are input/output. All + * input/output registers are represented with "+r". Output-only registers + * are represented with "=r". Do not specify any unused registers. The + * clobber list will tell the compiler that the hypercall modifies those + * registers, which is good enough. + */ + +/** + * fh_send_nmi - send NMI to virtual cpu(s). + * @vcpu_mask: send NMI to virtual cpu(s) specified by this mask. + * + * Returns 0 for success, or EINVAL for invalid vcpu_mask. + */ +static inline unsigned int fh_send_nmi(unsigned int vcpu_mask) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = FH_HCALL_TOKEN(FH_SEND_NMI); + r3 = vcpu_mask; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + +/* Arbitrary limits to avoid excessive memory allocation in hypervisor */ +#define FH_DTPROP_MAX_PATHLEN 4096 +#define FH_DTPROP_MAX_PROPLEN 32768 + +/** + * fh_partition_get_dtprop - get a property from a guest device tree. + * @handle: handle of partition whose device tree is to be accessed + * @dtpath_addr: physical address of device tree path to access + * @propname_addr: physical address of name of property + * @propvalue_addr: physical address of property value buffer + * @propvalue_len: length of buffer on entry, length of property on return + * + * Returns zero on success, non-zero on error. + */ +static inline unsigned int fh_partition_get_dtprop(int handle, + uint64_t dtpath_addr, + uint64_t propname_addr, + uint64_t propvalue_addr, + uint32_t *propvalue_len) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + register uintptr_t r6 __asm__("r6"); + register uintptr_t r7 __asm__("r7"); + register uintptr_t r8 __asm__("r8"); + register uintptr_t r9 __asm__("r9"); + register uintptr_t r10 __asm__("r10"); + + r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_DTPROP); + r3 = handle; + +#ifdef CONFIG_PHYS_64BIT + r4 = dtpath_addr >> 32; + r6 = propname_addr >> 32; + r8 = propvalue_addr >> 32; +#else + r4 = 0; + r6 = 0; + r8 = 0; +#endif + r5 = (uint32_t)dtpath_addr; + r7 = (uint32_t)propname_addr; + r9 = (uint32_t)propvalue_addr; + r10 = *propvalue_len; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), + "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), + "+r" (r8), "+r" (r9), "+r" (r10) + : : EV_HCALL_CLOBBERS8 + ); + + *propvalue_len = r4; + return r3; +} + +/** + * Set a property in a guest device tree. + * @handle: handle of partition whose device tree is to be accessed + * @dtpath_addr: physical address of device tree path to access + * @propname_addr: physical address of name of property + * @propvalue_addr: physical address of property value + * @propvalue_len: length of property + * + * Returns zero on success, non-zero on error. + */ +static inline unsigned int fh_partition_set_dtprop(int handle, + uint64_t dtpath_addr, + uint64_t propname_addr, + uint64_t propvalue_addr, + uint32_t propvalue_len) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r6 __asm__("r6"); + register uintptr_t r8 __asm__("r8"); + register uintptr_t r5 __asm__("r5"); + register uintptr_t r7 __asm__("r7"); + register uintptr_t r9 __asm__("r9"); + register uintptr_t r10 __asm__("r10"); + + r11 = FH_HCALL_TOKEN(FH_PARTITION_SET_DTPROP); + r3 = handle; + +#ifdef CONFIG_PHYS_64BIT + r4 = dtpath_addr >> 32; + r6 = propname_addr >> 32; + r8 = propvalue_addr >> 32; +#else + r4 = 0; + r6 = 0; + r8 = 0; +#endif + r5 = (uint32_t)dtpath_addr; + r7 = (uint32_t)propname_addr; + r9 = (uint32_t)propvalue_addr; + r10 = propvalue_len; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), + "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7), + "+r" (r8), "+r" (r9), "+r" (r10) + : : EV_HCALL_CLOBBERS8 + ); + + return r3; +} + +/** + * fh_partition_restart - reboot the current partition + * @partition: partition ID + * + * Returns an error code if reboot failed. Does not return if it succeeds. + */ +static inline unsigned int fh_partition_restart(unsigned int partition) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = FH_HCALL_TOKEN(FH_PARTITION_RESTART); + r3 = partition; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + +#define FH_PARTITION_STOPPED 0 +#define FH_PARTITION_RUNNING 1 +#define FH_PARTITION_STARTING 2 +#define FH_PARTITION_STOPPING 3 +#define FH_PARTITION_PAUSING 4 +#define FH_PARTITION_PAUSED 5 +#define FH_PARTITION_RESUMING 6 + +/** + * fh_partition_get_status - gets the status of a partition + * @partition: partition ID + * @status: returned status code + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_partition_get_status(unsigned int partition, + unsigned int *status) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + + r11 = FH_HCALL_TOKEN(FH_PARTITION_GET_STATUS); + r3 = partition; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "=r" (r4) + : : EV_HCALL_CLOBBERS2 + ); + + *status = r4; + + return r3; +} + +/** + * fh_partition_start - boots and starts execution of the specified partition + * @partition: partition ID + * @entry_point: guest physical address to start execution + * + * The hypervisor creates a 1-to-1 virtual/physical IMA mapping, so at boot + * time, guest physical address are the same as guest virtual addresses. + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_partition_start(unsigned int partition, + uint32_t entry_point, int load) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + + r11 = FH_HCALL_TOKEN(FH_PARTITION_START); + r3 = partition; + r4 = entry_point; + r5 = load; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5) + : : EV_HCALL_CLOBBERS3 + ); + + return r3; +} + +/** + * fh_partition_stop - stops another partition + * @partition: partition ID + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_partition_stop(unsigned int partition) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP); + r3 = partition; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + +/** + * struct fh_sg_list: definition of the fh_partition_memcpy S/G list + * @source: guest physical address to copy from + * @target: guest physical address to copy to + * @size: number of bytes to copy + * @reserved: reserved, must be zero + * + * The scatter/gather list for fh_partition_memcpy() is an array of these + * structures. The array must be guest physically contiguous. + * + * This structure must be aligned on 32-byte boundary, so that no single + * strucuture can span two pages. + */ +struct fh_sg_list { + uint64_t source; /**< guest physical address to copy from */ + uint64_t target; /**< guest physical address to copy to */ + uint64_t size; /**< number of bytes to copy */ + uint64_t reserved; /**< reserved, must be zero */ +} __attribute__ ((aligned(32))); + +/** + * fh_partition_memcpy - copies data from one guest to another + * @source: the ID of the partition to copy from + * @target: the ID of the partition to copy to + * @sg_list: guest physical address of an array of &fh_sg_list structures + * @count: the number of entries in @sg_list + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_partition_memcpy(unsigned int source, + unsigned int target, uint64_t sg_list, unsigned int count) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + register uintptr_t r6 __asm__("r6"); + register uintptr_t r7 __asm__("r7"); + + r11 = FH_HCALL_TOKEN(FH_PARTITION_MEMCPY); + r3 = source; + r4 = target; + r5 = (uint32_t) sg_list; + +#ifdef CONFIG_PHYS_64BIT + r6 = sg_list >> 32; +#else + r6 = 0; +#endif + r7 = count; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), + "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), "+r" (r7) + : : EV_HCALL_CLOBBERS5 + ); + + return r3; +} + +/** + * fh_dma_enable - enable DMA for the specified device + * @liodn: the LIODN of the I/O device for which to enable DMA + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_dma_enable(unsigned int liodn) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = FH_HCALL_TOKEN(FH_DMA_ENABLE); + r3 = liodn; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + +/** + * fh_dma_disable - disable DMA for the specified device + * @liodn: the LIODN of the I/O device for which to disable DMA + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_dma_disable(unsigned int liodn) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = FH_HCALL_TOKEN(FH_DMA_DISABLE); + r3 = liodn; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + + +/** + * fh_vmpic_get_msir - returns the MPIC-MSI register value + * @interrupt: the interrupt number + * @msir_val: returned MPIC-MSI register value + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_vmpic_get_msir(unsigned int interrupt, + unsigned int *msir_val) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + + r11 = FH_HCALL_TOKEN(FH_VMPIC_GET_MSIR); + r3 = interrupt; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "=r" (r4) + : : EV_HCALL_CLOBBERS2 + ); + + *msir_val = r4; + + return r3; +} + +/** + * fh_system_reset - reset the system + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_system_reset(void) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = FH_HCALL_TOKEN(FH_SYSTEM_RESET); + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "=r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + + +/** + * fh_err_get_info - get platform error information + * @queue id: + * 0 for guest error event queue + * 1 for global error event queue + * + * @pointer to store the platform error data: + * platform error data is returned in registers r4 - r11 + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_err_get_info(int queue, uint32_t *bufsize, + uint32_t addr_hi, uint32_t addr_lo, int peek) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + register uintptr_t r5 __asm__("r5"); + register uintptr_t r6 __asm__("r6"); + register uintptr_t r7 __asm__("r7"); + + r11 = FH_HCALL_TOKEN(FH_ERR_GET_INFO); + r3 = queue; + r4 = *bufsize; + r5 = addr_hi; + r6 = addr_lo; + r7 = peek; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), + "+r" (r7) + : : EV_HCALL_CLOBBERS5 + ); + + *bufsize = r4; + + return r3; +} + + +#define FH_VCPU_RUN 0 +#define FH_VCPU_IDLE 1 +#define FH_VCPU_NAP 2 + +/** + * fh_get_core_state - get the state of a vcpu + * + * @handle: handle of partition containing the vcpu + * @vcpu: vcpu number within the partition + * @state:the current state of the vcpu, see FH_VCPU_* + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_get_core_state(unsigned int handle, + unsigned int vcpu, unsigned int *state) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + + r11 = FH_HCALL_TOKEN(FH_GET_CORE_STATE); + r3 = handle; + r4 = vcpu; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "+r" (r4) + : : EV_HCALL_CLOBBERS2 + ); + + *state = r4; + return r3; +} + +/** + * fh_enter_nap - enter nap on a vcpu + * + * Note that though the API supports entering nap on a vcpu other + * than the caller, this may not be implmented and may return EINVAL. + * + * @handle: handle of partition containing the vcpu + * @vcpu: vcpu number within the partition + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_enter_nap(unsigned int handle, unsigned int vcpu) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + + r11 = FH_HCALL_TOKEN(FH_ENTER_NAP); + r3 = handle; + r4 = vcpu; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "+r" (r4) + : : EV_HCALL_CLOBBERS2 + ); + + return r3; +} + +/** + * fh_exit_nap - exit nap on a vcpu + * @handle: handle of partition containing the vcpu + * @vcpu: vcpu number within the partition + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_exit_nap(unsigned int handle, unsigned int vcpu) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + register uintptr_t r4 __asm__("r4"); + + r11 = FH_HCALL_TOKEN(FH_EXIT_NAP); + r3 = handle; + r4 = vcpu; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3), "+r" (r4) + : : EV_HCALL_CLOBBERS2 + ); + + return r3; +} +/** + * fh_claim_device - claim a "claimable" shared device + * @handle: fsl,hv-device-handle of node to claim + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_claim_device(unsigned int handle) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = FH_HCALL_TOKEN(FH_CLAIM_DEVICE); + r3 = handle; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} + +/** + * Run deferred DMA disabling on a partition's private devices + * + * This applies to devices which a partition owns either privately, + * or which are claimable and still actively owned by that partition, + * and which do not have the no-dma-disable property. + * + * @handle: partition (must be stopped) whose DMA is to be disabled + * + * Returns 0 for success, or an error code. + */ +static inline unsigned int fh_partition_stop_dma(unsigned int handle) +{ + register uintptr_t r11 __asm__("r11"); + register uintptr_t r3 __asm__("r3"); + + r11 = FH_HCALL_TOKEN(FH_PARTITION_STOP_DMA); + r3 = handle; + + asm volatile("bl epapr_hypercall_start" + : "+r" (r11), "+r" (r3) + : : EV_HCALL_CLOBBERS1 + ); + + return r3; +} +#endif diff --git a/bsps/powerpc/qoriq/include/bsp.h b/bsps/powerpc/qoriq/include/bsp.h new file mode 100644 index 0000000000..d7e9e95b3f --- /dev/null +++ b/bsps/powerpc/qoriq/include/bsp.h @@ -0,0 +1,128 @@ +/** + * @file + * + * @ingroup QorIQ + * + * @brief BSP API. + */ + +/* + * Copyright (c) 2010, 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef LIBBSP_POWERPC_QORIQ_BSP_H +#define LIBBSP_POWERPC_QORIQ_BSP_H + +#include <bspopts.h> + +#ifdef QORIQ_IS_HYPERVISOR_GUEST +#define QORIQ_THREAD_COUNT 1 +#else +#define QORIQ_THREAD_COUNT QORIQ_PHYSICAL_THREAD_COUNT +#endif + +#ifndef ASM + +#include <rtems.h> + +#include <bsp/default-initial-extension.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define BSP_FEATURE_IRQ_EXTENSION + +#define BSP_FDT_IS_SUPPORTED + +#define QORIQ_CHIP(alpha, num) ((alpha) * 10000 + (num)) + +#define QORIQ_CHIP_P1020 QORIQ_CHIP('P', 1020) + +#define QORIQ_CHIP_T2080 QORIQ_CHIP('T', 2080) + +#define QORIQ_CHIP_T4240 QORIQ_CHIP('T', 4240) + +#define QORIQ_CHIP_VARIANT QORIQ_CHIP(QORIQ_CHIP_SERIES, QORIQ_CHIP_NUMBER) + +#define QORIQ_CHIP_IS_T_VARIANT(variant) ((variant) / 10000 == 'T') + +extern unsigned BSP_bus_frequency; + +struct rtems_bsdnet_ifconfig; + +int BSP_tsec_attach( + struct rtems_bsdnet_ifconfig *config, + int attaching +); + +int qoriq_if_intercom_attach_detach( + struct rtems_bsdnet_ifconfig *config, + int attaching +); + +#if defined(HAS_UBOOT) + /* Routine to obtain U-Boot environment variables */ + const char *bsp_uboot_getenv( + const char *name + ); +#endif + +void bsp_restart(void *addr) RTEMS_NO_RETURN; + +void *bsp_idle_thread( uintptr_t ignored ); +#define BSP_IDLE_TASK_BODY bsp_idle_thread + +#define RTEMS_BSP_NETWORK_DRIVER_ATTACH BSP_tsec_attach +#define RTEMS_BSP_NETWORK_DRIVER_ATTACH4 qoriq_if_intercom_attach_detach + +#define RTEMS_BSP_NETWORK_DRIVER_NAME "tsec1" +#define RTEMS_BSP_NETWORK_DRIVER_NAME2 "tsec2" +#define RTEMS_BSP_NETWORK_DRIVER_NAME3 "tsec3" +#define RTEMS_BSP_NETWORK_DRIVER_NAME4 "intercom1" + +/* Internal data and functions */ + +typedef struct { + uint64_t addr; + uint64_t r3; + uint32_t reserved_0; + uint32_t pir; + uint64_t r6; + uint32_t reserved_1[8]; +} qoriq_start_spin_table; + +extern qoriq_start_spin_table * +qoriq_start_spin_table_addr[QORIQ_CPU_COUNT / QORIQ_THREAD_COUNT]; + +void qoriq_start_thread(void); + +void qoriq_restart_secondary_processor( + const qoriq_start_spin_table *spin_table +) RTEMS_NO_RETURN; + +void qoriq_initialize_exceptions(void *interrupt_stack_begin); + +void qoriq_decrementer_dispatch(void); + +extern uint32_t bsp_time_base_frequency; + +extern uint32_t qoriq_clock_frequency; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* ASM */ + +#endif /* LIBBSP_POWERPC_QORIQ_BSP_H */ diff --git a/bsps/powerpc/qoriq/include/bsp/intercom.h b/bsps/powerpc/qoriq/include/bsp/intercom.h new file mode 100644 index 0000000000..39b2ba938e --- /dev/null +++ b/bsps/powerpc/qoriq/include/bsp/intercom.h @@ -0,0 +1,125 @@ +/** + * @file + * + * @ingroup QorIQInterCom + * + * @brief Inter-Processor Communication API. + */ + +/* + * Copyright (c) 2011 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef LIBBSP_POWERPC_QORIQ_INTERCOM_H +#define LIBBSP_POWERPC_QORIQ_INTERCOM_H + +#include <rtems.h> +#include <rtems/chain.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup QorIQInterCom QorIQ - Inter-Processor Communication Support + * + * @ingroup QorIQ + * + * @brief Inter-processor communication support. + * + * @{ + */ + +uint32_t qoriq_spin_lock(uint32_t *lock); + +void qoriq_spin_unlock(uint32_t *lock, uint32_t msr); + +#define INTERCOM_CORE_COUNT 2 + +#define INTERCOM_SERVICE_COUNT 8 + +typedef enum { + INTERCOM_TYPE_MPCI, + INTERCOM_TYPE_UART_0, + INTERCOM_TYPE_UART_1, + INTERCOM_TYPE_NETWORK, + INTERCOM_TYPE_CUSTOM_0, + INTERCOM_TYPE_CUSTOM_1, + INTERCOM_TYPE_CUSTOM_2, + INTERCOM_TYPE_CUSTOM_3, + INTERCOM_TYPE_CUSTOM_4 +} intercom_type; + +typedef enum { + INTERCOM_SIZE_64 = 0, + INTERCOM_SIZE_512, + INTERCOM_SIZE_2K, + INTERCOM_SIZE_4K +} intercom_size; + +typedef struct intercom_packet { + union { + struct intercom_packet *next; + rtems_chain_node node; + } glue; + intercom_type type_index; + intercom_size size_index; + uint32_t flags; + size_t size; + uint32_t cache_line_alignment [2]; + char data []; +} intercom_packet; + +typedef void (*intercom_service)(intercom_packet *packet, void *arg); + +void qoriq_intercom_init(void); + +void qoriq_intercom_start(void); + +void qoriq_intercom_service_install(intercom_type type, intercom_service service, void *arg); + +void qoriq_intercom_service_remove(intercom_type type); + +intercom_packet *qoriq_intercom_allocate_packet(intercom_type type, intercom_size size); + +void qoriq_intercom_send_packets(int destination_core, intercom_packet *first, intercom_packet *last); + +static inline void qoriq_intercom_send_packet(int destination_core, intercom_packet *packet) +{ + qoriq_intercom_send_packets(destination_core, packet, packet); +} + +void qoriq_intercom_broadcast_packets(intercom_packet *first, intercom_packet *last); + +static inline void qoriq_intercom_broadcast_packet(intercom_packet *packet) +{ + qoriq_intercom_broadcast_packets(packet, packet); +} + +void qoriq_intercom_send(int destination_core, intercom_type type, intercom_size size, const void *buf, size_t n); + +void qoriq_intercom_free_packet(intercom_packet *packet); + +intercom_packet *qoriq_intercom_clone_packet(const intercom_packet *packet); + +#ifdef RTEMS_MULTIPROCESSING + extern rtems_mpci_table qoriq_intercom_mpci; +#endif + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_POWERPC_QORIQ_INTERCOM_H */ diff --git a/bsps/powerpc/qoriq/include/bsp/irq.h b/bsps/powerpc/qoriq/include/bsp/irq.h new file mode 100644 index 0000000000..e178057950 --- /dev/null +++ b/bsps/powerpc/qoriq/include/bsp/irq.h @@ -0,0 +1,401 @@ +/** + * @file + * + * @ingroup QorIQInterrupt + * + * @brief Interrupt API. + */ + +/* + * Copyright (c) 2010-2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef LIBBSP_POWERPC_QORIQ_IRQ_H +#define LIBBSP_POWERPC_QORIQ_IRQ_H + +#include <bsp.h> +#include <rtems/irq.h> +#include <rtems/irq-extension.h> +#include <rtems/score/processormask.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef QORIQ_IS_HYPERVISOR_GUEST + +#define BSP_INTERRUPT_VECTOR_MAX 1023 + +#else /* !QORIQ_IS_HYPERVISOR_GUEST */ + +#define QORIQ_IRQ_ERROR 0 + +#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) + +#define QORIQ_IRQ_PCI_EXPRESS_1 4 +#define QORIQ_IRQ_PCI_EXPRESS_2 5 +#define QORIQ_IRQ_PCI_EXPRESS_3 6 +#define QORIQ_IRQ_PCI_EXPRESS_4 7 +#define QORIQ_IRQ_PAMU 8 +#define QORIQ_IRQ_IFC 9 +#define QORIQ_IRQ_DMA_CHANNEL_1_1 12 +#define QORIQ_IRQ_DMA_CHANNEL_1_2 13 +#define QORIQ_IRQ_DMA_CHANNEL_1_3 14 +#define QORIQ_IRQ_DMA_CHANNEL_1_4 15 +#define QORIQ_IRQ_DMA_CHANNEL_2_1 16 +#define QORIQ_IRQ_DMA_CHANNEL_2_2 17 +#define QORIQ_IRQ_DMA_CHANNEL_2_3 18 +#define QORIQ_IRQ_DMA_CHANNEL_2_4 19 +#define QORIQ_IRQ_DUART_1 20 +#define QORIQ_IRQ_DUART_2 21 +#define QORIQ_IRQ_DUARL_I2C_1 22 +#define QORIQ_IRQ_DUARL_I2C_2 23 +#define QORIQ_IRQ_PCI_EXPRESS_1_INTA 24 +#define QORIQ_IRQ_PCI_EXPRESS_2_INTA 25 +#define QORIQ_IRQ_PCI_EXPRESS_3_INTA 26 +#define QORIQ_IRQ_PCI_EXPRESS_4_INTA 27 +#define QORIQ_IRQ_USB_1 28 +#define QORIQ_IRQ_USB_2 29 +#define QORIQ_IRQ_ESDHC 32 +#define QORIQ_IRQ_PERF_MON 36 +#define QORIQ_IRQ_ESPI 37 +#define QORIQ_IRQ_GPIO_2 38 +#define QORIQ_IRQ_GPIO_1 39 +#define QORIQ_IRQ_SATA_1 52 +#define QORIQ_IRQ_SATA_2 53 +#define QORIQ_IRQ_DMA_CHANNEL_1_5 60 +#define QORIQ_IRQ_DMA_CHANNEL_1_6 61 +#define QORIQ_IRQ_DMA_CHANNEL_1_7 62 +#define QORIQ_IRQ_DMA_CHANNEL_1_8 63 +#define QORIQ_IRQ_DMA_CHANNEL_2_5 64 +#define QORIQ_IRQ_DMA_CHANNEL_2_6 65 +#define QORIQ_IRQ_DMA_CHANNEL_2_7 66 +#define QORIQ_IRQ_DMA_CHANNEL_2_8 67 +#define QORIQ_IRQ_EVENT_PROC_UNIT_1 68 +#define QORIQ_IRQ_EVENT_PROC_UNIT_2 69 +#define QORIQ_IRQ_GPIO_3 70 +#define QORIQ_IRQ_GPIO_4 71 +#define QORIQ_IRQ_SEC_5_2_JOB_QUEUE_1 72 +#define QORIQ_IRQ_SEC_5_2_JOB_QUEUE_2 73 +#define QORIQ_IRQ_SEC_5_2_JOB_QUEUE_3 74 +#define QORIQ_IRQ_SEC_5_2_JOB_QUEUE_4 75 +#define QORIQ_IRQ_SEC_5_2_GLOBAL_ERROR 76 +#define QORIQ_IRQ_SEC_MON 77 +#define QORIQ_IRQ_EVENT_PROC_UNIT_3 78 +#define QORIQ_IRQ_EVENT_PROC_UNIT_4 79 +#define QORIQ_IRQ_FRAME_MGR 80 +#define QORIQ_IRQ_MDIO_1 84 +#define QORIQ_IRQ_MDIO_2 85 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_0 88 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_0 89 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_1 90 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_1 91 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_2 92 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_2 93 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_3 94 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_3 95 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_4 96 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_4 97 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_5 98 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_5 99 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_6 100 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_6 101 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_7 102 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_7 103 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_8 104 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_8 105 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_9 106 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_9 107 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_10 109 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_10 109 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_11 110 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_11 111 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_12 112 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_12 113 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_13 114 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_13 115 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_14 116 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_14 117 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_15 118 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_15 119 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_16 120 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_16 121 +#define QORIQ_IRQ_QUEUE_MGR_PORTAL_17 122 +#define QORIQ_IRQ_BUFFER_MGR_PORTAL_17 123 +#define QORIQ_IRQ_DMA_CHANNEL_3_1 240 +#define QORIQ_IRQ_DMA_CHANNEL_3_2 241 +#define QORIQ_IRQ_DMA_CHANNEL_3_3 242 +#define QORIQ_IRQ_DMA_CHANNEL_3_4 243 +#define QORIQ_IRQ_DMA_CHANNEL_3_5 244 +#define QORIQ_IRQ_DMA_CHANNEL_3_6 245 +#define QORIQ_IRQ_DMA_CHANNEL_3_7 246 +#define QORIQ_IRQ_DMA_CHANNEL_3_8 247 + +#define QORIQ_IRQ_EXT_BASE 256 + +#else /* QORIQ_CHIP_VARIANT */ + +/** + * @defgroup QoriqInterruptP1020 QorIQ - P1020 Internal Interrupt Sources + * + * @ingroup QorIQInterrupt + * + * @brief P1020 internal interrupt sources. + * + * @{ + */ + +#define QORIQ_IRQ_ETSEC_TX_1_GROUP_1 1 +#define QORIQ_IRQ_ETSEC_RX_1_GROUP_1 2 +#define QORIQ_IRQ_ETSEC_ER_1_GROUP_1 8 +#define QORIQ_IRQ_ETSEC_TX_3_GROUP_1 9 +#define QORIQ_IRQ_ETSEC_RX_3_GROUP_1 10 +#define QORIQ_IRQ_ETSEC_ER_3_GROUP_1 11 +#define QORIQ_IRQ_ETSEC_TX_2_GROUP_1 35 +#define QORIQ_IRQ_ETSEC_RX_2_GROUP_1 36 +#define QORIQ_IRQ_TDM 46 +#define QORIQ_IRQ_TDM_ERROR 47 +#define QORIQ_IRQ_ETSEC_ER_2_GROUP_1 51 + +/** @} */ + +/** + * @defgroup QoriqInterruptP2020 QorIQ - P2020 Internal Interrupt Sources + * + * @ingroup QorIQInterrupt + * + * @brief P2020 internal interrupt sources. + * + * @{ + */ + +#define QORIQ_IRQ_L2_CACHE 0 +#define QORIQ_IRQ_ECM 1 +#define QORIQ_IRQ_DDR_CONTROLLER 2 +#define QORIQ_IRQ_PCI_EXPRESS_3 8 +#define QORIQ_IRQ_PCI_EXPRESS_2 9 +#define QORIQ_IRQ_PCI_EXPRESS_1 10 +#define QORIQ_IRQ_SRIO_ERR_WRT_1_2 32 +#define QORIQ_IRQ_SRIO_OUT_DOORBELL_1 33 +#define QORIQ_IRQ_SRIO_IN_DOORBELL_1 34 +#define QORIQ_IRQ_SRIO_OUT_MSG_1 37 +#define QORIQ_IRQ_SRIO_IN_MSG_1 38 +#define QORIQ_IRQ_SRIO_OUT_MSG_2 39 +#define QORIQ_IRQ_SRIO_IN_MSG_2 40 + +/** @} */ + +/** + * @defgroup QoriqInterruptAll QorIQ - Internal Interrupt Sources + * + * @ingroup QorIQInterrupt + * + * @brief Internal interrupt sources. + * + * @{ + */ + +#define QORIQ_IRQ_ELBC 3 +#define QORIQ_IRQ_DMA_CHANNEL_1_1 4 +#define QORIQ_IRQ_DMA_CHANNEL_2_1 5 +#define QORIQ_IRQ_DMA_CHANNEL_3_1 6 +#define QORIQ_IRQ_DMA_CHANNEL_4_1 7 +#define QORIQ_IRQ_USB_1 12 +#define QORIQ_IRQ_ETSEC_TX_1 13 +#define QORIQ_IRQ_ETSEC_RX_1 14 +#define QORIQ_IRQ_ETSEC_TX_3 15 +#define QORIQ_IRQ_ETSEC_RX_3 16 +#define QORIQ_IRQ_ETSEC_ER_3 17 +#define QORIQ_IRQ_ETSEC_ER_1 18 +#define QORIQ_IRQ_ETSEC_TX_2 19 +#define QORIQ_IRQ_ETSEC_RX_2 20 +#define QORIQ_IRQ_ETSEC_ER_2 24 +#define QORIQ_IRQ_DUART_1 26 +#define QORIQ_IRQ_I2C 27 +#define QORIQ_IRQ_PERFORMANCE_MONITOR 28 +#define QORIQ_IRQ_SECURITY_1 29 +#define QORIQ_IRQ_USB_2 30 +#define QORIQ_IRQ_GPIO 31 +#define QORIQ_IRQ_SECURITY_2 42 +#define QORIQ_IRQ_ESPI 43 +#define QORIQ_IRQ_ETSEC_IEEE_1588_1 52 +#define QORIQ_IRQ_ETSEC_IEEE_1588_2 53 +#define QORIQ_IRQ_ETSEC_IEEE_1588_3 54 +#define QORIQ_IRQ_ESDHC 56 +#define QORIQ_IRQ_DMA_CHANNEL_1_2 60 +#define QORIQ_IRQ_DMA_CHANNEL_2_2 61 +#define QORIQ_IRQ_DMA_CHANNEL_3_2 62 +#define QORIQ_IRQ_DMA_CHANNEL_4_2 63 + +/** @} */ + +#define QORIQ_IRQ_EXT_BASE 64 + +#endif /* QORIQ_CHIP_VARIANT */ + +/** + * @defgroup QoriqInterruptExternal QorIQ - External Interrupt Sources + * + * @ingroup QorIQInterrupt + * + * @brief External interrupt sources. + * + * @{ + */ + +#define QORIQ_IRQ_EXT_0 (QORIQ_IRQ_EXT_BASE + 0) +#define QORIQ_IRQ_EXT_1 (QORIQ_IRQ_EXT_BASE + 1) +#define QORIQ_IRQ_EXT_2 (QORIQ_IRQ_EXT_BASE + 2) +#define QORIQ_IRQ_EXT_3 (QORIQ_IRQ_EXT_BASE + 3) +#define QORIQ_IRQ_EXT_4 (QORIQ_IRQ_EXT_BASE + 4) +#define QORIQ_IRQ_EXT_5 (QORIQ_IRQ_EXT_BASE + 5) +#define QORIQ_IRQ_EXT_6 (QORIQ_IRQ_EXT_BASE + 6) +#define QORIQ_IRQ_EXT_7 (QORIQ_IRQ_EXT_BASE + 7) +#define QORIQ_IRQ_EXT_8 (QORIQ_IRQ_EXT_BASE + 8) +#define QORIQ_IRQ_EXT_9 (QORIQ_IRQ_EXT_BASE + 9) +#define QORIQ_IRQ_EXT_10 (QORIQ_IRQ_EXT_BASE + 10) +#define QORIQ_IRQ_EXT_11 (QORIQ_IRQ_EXT_BASE + 11) + +/** @} */ + +/** + * @defgroup QoriqInterruptIPI QorIQ - Interprocessor Interrupts + * + * @ingroup QorIQInterrupt + * + * @brief Interprocessor interrupts. + * + * @{ + */ + +#define QORIQ_IRQ_IPI_BASE (QORIQ_IRQ_EXT_11 + 1) +#define QORIQ_IRQ_IPI_0 (QORIQ_IRQ_IPI_BASE + 0) +#define QORIQ_IRQ_IPI_1 (QORIQ_IRQ_IPI_BASE + 1) +#define QORIQ_IRQ_IPI_2 (QORIQ_IRQ_IPI_BASE + 2) +#define QORIQ_IRQ_IPI_3 (QORIQ_IRQ_IPI_BASE + 3) + +/** @} */ + +/** + * @defgroup QoriqInterruptIPI QorIQ - Message Interrupts + * + * @ingroup QorIQInterrupt + * + * @brief Message interrupts. + * + * @{ + */ + +#define QORIQ_IRQ_MI_BASE (QORIQ_IRQ_IPI_3 + 1) +#define QORIQ_IRQ_MI_0 (QORIQ_IRQ_MI_BASE + 0) +#define QORIQ_IRQ_MI_1 (QORIQ_IRQ_MI_BASE + 1) +#define QORIQ_IRQ_MI_2 (QORIQ_IRQ_MI_BASE + 2) +#define QORIQ_IRQ_MI_3 (QORIQ_IRQ_MI_BASE + 3) +#define QORIQ_IRQ_MI_4 (QORIQ_IRQ_MI_BASE + 4) +#define QORIQ_IRQ_MI_5 (QORIQ_IRQ_MI_BASE + 5) +#define QORIQ_IRQ_MI_6 (QORIQ_IRQ_MI_BASE + 6) +#define QORIQ_IRQ_MI_7 (QORIQ_IRQ_MI_BASE + 7) + +/** @} */ + +/** + * @defgroup QoriqInterruptIPI QorIQ - Shared Message Signaled Interrupts + * + * @ingroup QorIQInterrupt + * + * @brief Shared message signaled interrupts. + * + * @{ + */ + +#define QORIQ_IRQ_MSI_BASE (QORIQ_IRQ_MI_7 + 1) +#define QORIQ_IRQ_MSI_0 (QORIQ_IRQ_MSI_BASE + 0) +#define QORIQ_IRQ_MSI_1 (QORIQ_IRQ_MSI_BASE + 1) +#define QORIQ_IRQ_MSI_2 (QORIQ_IRQ_MSI_BASE + 2) +#define QORIQ_IRQ_MSI_3 (QORIQ_IRQ_MSI_BASE + 3) +#define QORIQ_IRQ_MSI_4 (QORIQ_IRQ_MSI_BASE + 4) +#define QORIQ_IRQ_MSI_5 (QORIQ_IRQ_MSI_BASE + 5) +#define QORIQ_IRQ_MSI_6 (QORIQ_IRQ_MSI_BASE + 6) +#define QORIQ_IRQ_MSI_7 (QORIQ_IRQ_MSI_BASE + 7) + +/** @} */ + +/** + * @defgroup QoriqInterruptIPI QorIQ - Global Timer Interrupts + * + * @ingroup QorIQInterrupt + * + * @brief Global Timer interrupts. + * + * @{ + */ + +#define QORIQ_IRQ_GT_BASE (QORIQ_IRQ_MSI_7 + 1) +#define QORIQ_IRQ_GT_A_0 (QORIQ_IRQ_GT_BASE + 0) +#define QORIQ_IRQ_GT_A_1 (QORIQ_IRQ_GT_BASE + 1) +#define QORIQ_IRQ_GT_A_2 (QORIQ_IRQ_GT_BASE + 2) +#define QORIQ_IRQ_GT_A_3 (QORIQ_IRQ_GT_BASE + 3) +#define QORIQ_IRQ_GT_B_0 (QORIQ_IRQ_GT_BASE + 4) +#define QORIQ_IRQ_GT_B_1 (QORIQ_IRQ_GT_BASE + 5) +#define QORIQ_IRQ_GT_B_2 (QORIQ_IRQ_GT_BASE + 6) +#define QORIQ_IRQ_GT_B_3 (QORIQ_IRQ_GT_BASE + 7) + +#define BSP_INTERRUPT_VECTOR_MAX QORIQ_IRQ_GT_B_3 + +/** @} */ + +#endif /* QORIQ_IS_HYPERVISOR_GUEST */ + +/** + * @defgroup QorIQInterrupt QorIQ - Interrupt Support + * + * @ingroup QorIQ + * + * @brief Interrupt support. + * + * @{ + */ + +#define BSP_INTERRUPT_VECTOR_MIN 0 + +#define QORIQ_PIC_PRIORITY_LOWEST 1 +#define QORIQ_PIC_PRIORITY_HIGHEST 15 +#define QORIQ_PIC_PRIORITY_DISABLED 0 +#define QORIQ_PIC_PRIORITY_INVALID (QORIQ_PIC_PRIORITY_HIGHEST + 1) +#define QORIQ_PIC_PRIORITY_DEFAULT (QORIQ_PIC_PRIORITY_LOWEST + 1) +#define QORIQ_PIC_PRIORITY_IS_VALID(p) \ + ((p) >= QORIQ_PIC_PRIORITY_DISABLED && (p) <= QORIQ_PIC_PRIORITY_HIGHEST) + +rtems_status_code qoriq_pic_set_priority( + rtems_vector_number vector, + int new_priority, + int *old_priority +); + +void bsp_interrupt_set_affinity( + rtems_vector_number vector, + const Processor_mask *affinity +); + +void bsp_interrupt_get_affinity( + rtems_vector_number vector, + Processor_mask *affinity +); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_POWERPC_QORIQ_IRQ_H */ diff --git a/bsps/powerpc/qoriq/include/bsp/mmu.h b/bsps/powerpc/qoriq/include/bsp/mmu.h new file mode 100644 index 0000000000..4cacb1b375 --- /dev/null +++ b/bsps/powerpc/qoriq/include/bsp/mmu.h @@ -0,0 +1,101 @@ +/** + * @file + * + * @ingroup QorIQMMU + * + * @brief MMU API. + */ + +/* + * Copyright (c) 2011-2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef LIBBSP_POWERPC_QORIQ_MMU_H +#define LIBBSP_POWERPC_QORIQ_MMU_H + +#include <stdint.h> +#include <stdbool.h> + +#include <bspopts.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup QorIQMMU QorIQ - MMU Support + * + * @ingroup QorIQ + * + * @brief MMU support. + * + * @{ + */ + +#define QORIQ_MMU_MIN_POWER 12 +#define QORIQ_MMU_MAX_POWER 30 +#define QORIQ_MMU_POWER_STEP 2 + +typedef struct { + uintptr_t begin; + uintptr_t last; + uint32_t mas1; + uint32_t mas2; + uint32_t mas3; + uint32_t mas7; +} qoriq_mmu_entry; + +typedef struct { + int count; + qoriq_mmu_entry entries [QORIQ_TLB1_ENTRY_COUNT]; +} qoriq_mmu_context; + +void qoriq_mmu_context_init(qoriq_mmu_context *self); + +bool qoriq_mmu_add( + qoriq_mmu_context *self, + uintptr_t begin, + uintptr_t last, + uint32_t mas1, + uint32_t mas2, + uint32_t mas3, + uint32_t mas7 +); + +void qoriq_mmu_partition(qoriq_mmu_context *self, int max_count); + +void qoriq_mmu_write_to_tlb1(qoriq_mmu_context *self, int first_tlb); + +void qoriq_mmu_change_perm(uint32_t test, uint32_t set, uint32_t clear); + +void qoriq_mmu_config(bool boot_processor, int first_tlb, int scratch_tlb); + +void qoriq_tlb1_write( + int esel, + uint32_t mas1, + uint32_t mas2, + uint32_t mas3, + uint32_t mas7, + uintptr_t ea, + int tsize +); + +void qoriq_tlb1_invalidate(int esel); + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_POWERPC_QORIQ_MMU_H */ diff --git a/bsps/powerpc/qoriq/include/bsp/qoriq.h b/bsps/powerpc/qoriq/include/bsp/qoriq.h new file mode 100644 index 0000000000..2d28d0aec7 --- /dev/null +++ b/bsps/powerpc/qoriq/include/bsp/qoriq.h @@ -0,0 +1,559 @@ +/** + * @file + * + * @ingroup QorIQ + * + * @brief QorIQ Configuration, Control and Status Registers. + */ + +/* + * Copyright (c) 2010-2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef LIBBSP_POWERPC_QORIQ_QORIQ_H +#define LIBBSP_POWERPC_QORIQ_QORIQ_H + +#include <bsp.h> +#include <bsp/tsec.h> +#include <bsp/utility.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define QORIQ_FILL(a, b, s) uint8_t reserved_ ## b [b - a - sizeof(s)] +#define QORIQ_RESERVE(a, b) uint8_t reserved_ ## b [b - a] + +typedef struct { + uint32_t reg; + QORIQ_FILL(0x00000, 0x00010, uint32_t); +} qoriq_pic_reg; + +typedef struct { + uint32_t ccr; + QORIQ_FILL(0x00000, 0x00010, uint32_t); + uint32_t bcr; + QORIQ_FILL(0x00010, 0x00020, uint32_t); + uint32_t vpr; + QORIQ_FILL(0x00020, 0x00030, uint32_t); + uint32_t dr; + QORIQ_FILL(0x00030, 0x00040, uint32_t); +} qoriq_pic_global_timer; + +#define GTCCR_TOG BSP_BBIT32(0) +#define GTCCR_COUNT_GET(reg) BSP_BFLD32GET(reg, 1, 31) + +#define GTBCR_CI BSP_BBIT32(0) +#define GTBCR_COUNT(val) BSP_BFLD32(val, 1, 31) +#define GTBCR_COUNT_GET(reg) BSP_BFLD32GET(reg, 1, 31) +#define GTBCR_COUNT_SET(reg, val) BSP_BFLD32SET(reg, val, 1, 31) + +typedef struct { + uint32_t misc; + QORIQ_FILL(0x00000, 0x00010, uint32_t); + uint32_t internal [2]; + QORIQ_FILL(0x00010, 0x00020, uint32_t [2]); +} qoriq_pic_bit_field; + +typedef struct { + uint32_t vpr; + QORIQ_FILL(0x00000, 0x00010, uint32_t); + uint32_t dr; + QORIQ_FILL(0x00010, 0x00020, uint32_t); +} qoriq_pic_src_cfg; + +typedef struct { + QORIQ_RESERVE(0x00000, 0x00040); + qoriq_pic_reg ipidr [4]; + uint32_t ctpr; + QORIQ_FILL(0x00080, 0x00090, uint32_t); + uint32_t whoami; + QORIQ_FILL(0x00090, 0x000a0, uint32_t); + uint32_t iack; + QORIQ_FILL(0x000a0, 0x000b0, uint32_t); + uint32_t eoi; + QORIQ_FILL(0x000b0, 0x01000, uint32_t); +} qoriq_pic_per_cpu; + +typedef struct { + uint32_t brr1; + QORIQ_FILL(0x00000, 0x00010, uint32_t); + uint32_t brr2; + QORIQ_FILL(0x00010, 0x00040, uint32_t); + qoriq_pic_reg ipidr [4]; + uint32_t ctpr; + QORIQ_FILL(0x00080, 0x00090, uint32_t); + uint32_t whoami; + QORIQ_FILL(0x00090, 0x000a0, uint32_t); + uint32_t iack; + QORIQ_FILL(0x000a0, 0x000b0, uint32_t); + uint32_t eoi; + QORIQ_FILL(0x000b0, 0x01000, uint32_t); + uint32_t frr; + QORIQ_FILL(0x01000, 0x01020, uint32_t); + uint32_t gcr; + QORIQ_FILL(0x01020, 0x01080, uint32_t); + uint32_t vir; + QORIQ_FILL(0x01080, 0x01090, uint32_t); + uint32_t pir; + QORIQ_FILL(0x01090, 0x010a0, uint32_t); + qoriq_pic_reg ipivpr [4]; + uint32_t svr; + QORIQ_FILL(0x010e0, 0x010f0, uint32_t); + uint32_t tfrra; + QORIQ_FILL(0x010f0, 0x01100, uint32_t); + qoriq_pic_global_timer gta [4]; + QORIQ_RESERVE(0x01200, 0x01300); + uint32_t tcra; + QORIQ_FILL(0x01300, 0x01308, uint32_t); + uint32_t erqsr; + QORIQ_FILL(0x01308, 0x01310, uint32_t); + qoriq_pic_bit_field irqsr; + qoriq_pic_bit_field cisr; + qoriq_pic_bit_field pm [4]; + QORIQ_RESERVE(0x013d0, 0x01400); + qoriq_pic_reg msgr03 [4]; + QORIQ_RESERVE(0x01440, 0x01500); + uint32_t mer03; + QORIQ_FILL(0x01500, 0x01510, uint32_t); + uint32_t msr03; + QORIQ_FILL(0x01510, 0x01600, uint32_t); + qoriq_pic_reg msir [8]; + QORIQ_RESERVE(0x01680, 0x01720); + uint32_t msisr; + QORIQ_FILL(0x01720, 0x01740, uint32_t); + uint32_t msiir; + QORIQ_FILL(0x01740, 0x020f0, uint32_t); + uint32_t tfrrb; + QORIQ_FILL(0x020f0, 0x02100, uint32_t); + qoriq_pic_global_timer gtb [4]; + QORIQ_RESERVE(0x02200, 0x02300); + uint32_t tcrb; + QORIQ_FILL(0x02300, 0x02400, uint32_t); + qoriq_pic_reg msgr47 [4]; + QORIQ_RESERVE(0x02440, 0x02500); + uint32_t mer47; + QORIQ_FILL(0x02500, 0x02510, uint32_t); + uint32_t msr47; + QORIQ_FILL(0x02510, 0x10000, uint32_t); + qoriq_pic_src_cfg ei [12]; + QORIQ_RESERVE(0x10180, 0x10200); + qoriq_pic_src_cfg ii_0 [160]; + qoriq_pic_src_cfg mi [8]; + QORIQ_RESERVE(0x11700, 0x11c00); + qoriq_pic_src_cfg msi [8]; + QORIQ_RESERVE(0x11d00, 0x13000); + qoriq_pic_src_cfg ii_1 [96]; + QORIQ_RESERVE(0x13c00, 0x20000); + qoriq_pic_per_cpu per_cpu [2]; +} qoriq_pic; + +#define GTTCR_ROVR(val) BSP_BFLD32(val, 5, 7) +#define GTTCR_ROVR_GET(reg) BSP_BFLD32GET(reg, 5, 7) +#define GTTCR_ROVR_SET(reg, val) BSP_BFLD32SET(reg, val, 5, 7) +#define GTTCR_RTM BSP_BBIT32(15) +#define GTTCR_CLKR(val) BSP_BFLD32(val, 22, 23) +#define GTTCR_CLKR_GET(reg) BSP_BFLD32GET(reg, 22, 23) +#define GTTCR_CLKR_SET(reg, val) BSP_BFLD32SET(reg, val, 22, 23) +#define GTTCR_CASC(val) BSP_BFLD32(val, 29, 31) +#define GTTCR_CASC_GET(reg) BSP_BFLD32GET(reg, 29, 31) +#define GTTCR_CASC_SET(reg, val) BSP_BFLD32SET(reg, val, 29, 31) + +typedef struct { +} qoriq_uart; + +typedef struct { + uint32_t gpdir; + uint32_t gpodr; + uint32_t gpdat; + uint32_t gpier; + uint32_t gpimr; + uint32_t gpicr; + uint32_t gpibe; + QORIQ_RESERVE(0x001c, 0x1000); +} qoriq_gpio; + +typedef struct { + QORIQ_RESERVE(0x000, 0x100); + uint16_t caplength; + uint16_t hciversion; + uint32_t hcsparams; + uint32_t hccparams; + QORIQ_RESERVE(0x10c, 0x120); + uint32_t dciversion; + uint32_t dccparams; + QORIQ_RESERVE(0x128, 0x140); + uint32_t usbcmd; + uint32_t usbsts; + uint32_t usbintr; + uint32_t frindex; + QORIQ_RESERVE(0x150, 0x154); + union { + uint32_t periodiclistbase; + uint32_t deviceaddr; + } perbase_devaddr; + union { + uint32_t asynclistaddr; + uint32_t addr; + } async_addr; + QORIQ_RESERVE(0x15c, 0x160); + uint32_t burstsize; + uint32_t txfilltuning; + QORIQ_RESERVE(0x168, 0x170); + uint32_t viewport; + QORIQ_RESERVE(0x174, 0x180); + uint32_t configflag; + uint32_t portsc1; + QORIQ_RESERVE(0x188, 0x1a8); + uint32_t usbmode; + uint32_t endptsetupstat; + uint32_t endpointprime; + uint32_t endptflush; + uint32_t endptstatus; + uint32_t endptcomplete; + uint32_t endptctrl[6]; + QORIQ_RESERVE(0x1d8, 0x400); + uint32_t snoop1; + uint32_t snoop2; + uint32_t age_cnt_thresh; + uint32_t pri_ctrl; + uint32_t si_ctrl; + QORIQ_RESERVE(0x414, 0x500); + uint32_t control; +} qoriq_usb; + +typedef struct { + uint32_t dsaddr; + uint32_t blkattr; + uint32_t cmdarg; + uint32_t xfertyp; + uint32_t cmdrsp0; + uint32_t cmdrsp1; + uint32_t cmdrsp2; + uint32_t cmdrsp3; + uint32_t datport; + uint32_t prsstat; + uint32_t proctl; + uint32_t sysctl; + uint32_t irqstat; + uint32_t irqstaten; + uint32_t irqsigen; + uint32_t autoc12err; + uint32_t hostcapblt; + uint32_t wml; + QORIQ_FILL(0x00044, 0x00050, uint32_t); + uint32_t fevt; + QORIQ_FILL(0x00050, 0x000fc, uint32_t); + uint32_t hostver; + QORIQ_FILL(0x000fc, 0x0040c, uint32_t); + uint32_t dcr; +} qoriq_esdhc; + +#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) + +typedef struct { + uint32_t ccsrbarh; + uint32_t ccsrbarl; + uint32_t ccsrar; + uint32_t altcbarh; + uint32_t altcbarl; + uint32_t altcar; + uint32_t bstrh; + uint32_t bstrl; + uint32_t bstar; +} qoriq_lcc; + +#define LCC_BSTAR_EN BSP_BBIT32(0) + +typedef struct { + uint32_t lawbarh; + uint32_t lawbarl; + uint32_t lawar; + uint32_t reserved_0xc; +} qoriq_law; + +typedef struct { + uint32_t reserved_0x0[640]; + uint32_t qmbm_warmrst; +} qoriq_dcfg; + +typedef struct { + QORIQ_RESERVE(0x0000, 0x1000); +} qoriq_bman; + +typedef struct { + QORIQ_RESERVE(0x0000, 0x1000); +} qoriq_qman; + +typedef struct { + QORIQ_RESERVE(0x000000, 0x100000); +} qoriq_fman; + +typedef struct { + qoriq_lcc lcc; + QORIQ_FILL(0x000000, 0x000c00, qoriq_lcc); + qoriq_law law [32]; + QORIQ_FILL(0x000c00, 0x001000, qoriq_law [32]); + QORIQ_RESERVE(0x001000, 0x040000); + qoriq_pic pic; + QORIQ_FILL(0x040000, 0x070000, qoriq_pic); + QORIQ_RESERVE(0x070000, 0x0e0000); + qoriq_dcfg dcfg; + QORIQ_FILL(0x0e0000, 0x0e1000, qoriq_dcfg); + QORIQ_RESERVE(0x0e1000, 0x114000); + qoriq_esdhc esdhc; + QORIQ_FILL(0x114000, 0x115000, qoriq_esdhc); + QORIQ_RESERVE(0x115000, 0x11c500); + qoriq_uart uart_0; + QORIQ_FILL(0x11c500, 0x11c600, qoriq_uart); + qoriq_uart uart_1; + QORIQ_FILL(0x11c600, 0x11d500, qoriq_uart); + qoriq_uart uart_2; + QORIQ_FILL(0x11d500, 0x11d600, qoriq_uart); + qoriq_uart uart_3; + QORIQ_FILL(0x11d600, 0x11e000, qoriq_uart); + QORIQ_RESERVE(0x11e000, 0x130000); + qoriq_gpio gpio[4]; + QORIQ_RESERVE(0x134000, 0x210000); + qoriq_usb usb_1; + QORIQ_FILL(0x210000, 0x211000, qoriq_usb); + QORIQ_RESERVE(0x211000, 0x318000); + qoriq_qman qman; + QORIQ_RESERVE(0x319000, 0x31a000); + qoriq_bman bman; + QORIQ_RESERVE(0x31b000, 0x400000); + qoriq_fman fman[2]; + QORIQ_RESERVE(0x600000, 0x2000000); +} qoriq_ccsr; + +#else /* QORIQ_CHIP_VARIANT */ + +typedef struct { + uint32_t ccsrbar; + uint32_t reserved_0; + uint32_t altcbar; + uint32_t reserved_1; + uint32_t altcar; + uint32_t reserved_2 [3]; + uint32_t bptr; +} qoriq_lcc; + +#define CCSRBAR_BASE_ADDR(val) BSP_BFLD32(val, 8, 23) +#define CCSRBAR_BASE_ADDR_GET(reg) BSP_BFLD32GET(reg, 8, 23) +#define CCSRBAR_BASE_ADDR_SET(reg, val) BSP_BFLD32SET(reg, val, 8, 23) + +#define ALTCBAR_BASE_ADDR(val) BSP_BFLD32(val, 8, 23) +#define ALTCBAR_BASE_ADDR_GET(reg) BSP_BFLD32GET(reg, 8, 23) +#define ALTCBAR_BASE_ADDR_SET(reg, val) BSP_BFLD32SET(reg, val, 8, 23) + +#define ALTCAR_EN BSP_BBIT32(0) +#define ALTCAR_TRGT_ID(val) BSP_BFLD32(val, 8, 11) +#define ALTCAR_TRGT_ID_GET(reg) BSP_BFLD32GET(reg, 8, 11) +#define ALTCAR_TRGT_ID_SET(reg, val) BSP_BFLD32SET(reg, val, 8, 11) + +#define BPTR_EN BSP_BBIT32(0) +#define BPTR_BOOT_PAGE(val) BSP_BFLD32(val, 8, 31) +#define BPTR_BOOT_PAGE_GET(reg) BSP_BFLD32GET(reg, 8, 31) +#define BPTR_BOOT_PAGE_SET(reg, val) BSP_BFLD32SET(reg, val, 8, 31) + +typedef struct { + uint32_t bar; + uint32_t reserved_0; + uint32_t ar; + uint32_t reserved_1 [5]; +} qoriq_law; + +#define LAWBAR_BASE_ADDR(val) BSP_BFLD32(val, 8, 31) +#define LAWBAR_BASE_ADDR_GET(reg) BSP_BFLD32GET(reg, 8, 31) +#define LAWBAR_BASE_ADDR_SET(reg, val) BSP_BFLD32SET(reg, val, 8, 31) + +#define LAWAR_EN BSP_BBIT32(0) +#define LAWAR_TRGT(val) BSP_BFLD32(val, 8, 11) +#define LAWAR_TRGT_GET(reg) BSP_BFLD32GET(reg, 8, 11) +#define LAWAR_TRGT_SET(reg, val) BSP_BFLD32SET(reg, val, 8, 11) +#define LAWAR_SIZE(val) BSP_BFLD32(val, 26, 31) +#define LAWAR_SIZE_GET(reg) BSP_BFLD32GET(reg, 26, 31) +#define LAWAR_SIZE_SET(reg, val) BSP_BFLD32SET(reg, val, 26, 31) + +typedef struct { +} qoriq_ecm; + +typedef struct { +} qoriq_ddr_controller; + +typedef struct { +} qoriq_i2c; + +typedef struct { +} qoriq_local_bus; + +typedef struct { +} qoriq_spi; + +typedef struct { +} qoriq_pci_express; + +typedef struct { +} qoriq_tdm; + +typedef struct { +} qoriq_l2_cache; + +typedef struct { +} qoriq_dma; + +typedef struct { +} qoriq_tdm_dma; + +typedef struct { +} qoriq_sec; + +typedef struct { +} qoriq_serial_rapid_io; + +typedef struct { +} qoriq_global_utilities; + +typedef struct { +} qoriq_performance_monitor; + +typedef struct { +} qoriq_debug_watchpoint; + +typedef struct { +} qoriq_serdes; + +typedef struct { +} qoriq_boot_rom; + +typedef struct { + qoriq_lcc lcc; + QORIQ_FILL(0x00000, 0x00c08, qoriq_lcc); + qoriq_law law [12]; + QORIQ_FILL(0x00c08, 0x01000, qoriq_law [12]); + qoriq_ecm ecm; + QORIQ_FILL(0x01000, 0x02000, qoriq_ecm); + qoriq_ddr_controller ddr_controller; + QORIQ_FILL(0x02000, 0x03000, qoriq_ddr_controller); + qoriq_i2c i2c; + QORIQ_FILL(0x03000, 0x04000, qoriq_i2c); + QORIQ_RESERVE(0x04000, 0x04500); + qoriq_uart uart_0; + QORIQ_FILL(0x04500, 0x04600, qoriq_uart); + qoriq_uart uart_1; + QORIQ_FILL(0x04600, 0x04700, qoriq_uart); + QORIQ_RESERVE(0x04700, 0x05000); + qoriq_local_bus local_bus; + QORIQ_FILL(0x05000, 0x06000, qoriq_local_bus); + qoriq_spi spi; + QORIQ_FILL(0x06000, 0x07000, qoriq_spi); + QORIQ_RESERVE(0x07000, 0x08000); + qoriq_pci_express pci_express_3; + QORIQ_FILL(0x08000, 0x09000, qoriq_pci_express); + qoriq_pci_express pci_express_2; + QORIQ_FILL(0x09000, 0x0a000, qoriq_pci_express); + qoriq_pci_express pci_express_1; + QORIQ_FILL(0x0a000, 0x0b000, qoriq_pci_express); + QORIQ_RESERVE(0x0b000, 0x0c000); + qoriq_dma dma_2; + QORIQ_FILL(0x0c000, 0x0d000, qoriq_dma); + QORIQ_RESERVE(0x0d000, 0x0f000); + qoriq_gpio gpio; + QORIQ_RESERVE(0x10000, 0x16000); + qoriq_tdm tdm; + QORIQ_FILL(0x16000, 0x17000, qoriq_tdm); + QORIQ_RESERVE(0x17000, 0x20000); + qoriq_l2_cache l2_cache; + QORIQ_FILL(0x20000, 0x21000, qoriq_l2_cache); + qoriq_dma dma_1; + QORIQ_FILL(0x21000, 0x22000, qoriq_dma); + qoriq_usb usb_1; + QORIQ_FILL(0x22000, 0x23000, qoriq_usb); + qoriq_usb usb_2; + QORIQ_FILL(0x23000, 0x24000, qoriq_usb); + tsec_registers tsec_1; + QORIQ_FILL(0x24000, 0x25000, tsec_registers); + tsec_registers tsec_2; + QORIQ_FILL(0x25000, 0x26000, tsec_registers); + tsec_registers tsec_3; + QORIQ_FILL(0x26000, 0x27000, tsec_registers); + QORIQ_RESERVE(0x27000, 0x2c000); + qoriq_tdm_dma tdm_dma; + QORIQ_FILL(0x2c000, 0x2d000, qoriq_tdm_dma); + QORIQ_RESERVE(0x2d000, 0x2e000); + qoriq_esdhc esdhc; + QORIQ_FILL(0x2e000, 0x2f000, qoriq_esdhc); + QORIQ_RESERVE(0x2f000, 0x30000); + qoriq_sec sec; + QORIQ_FILL(0x30000, 0x31000, qoriq_sec); + QORIQ_RESERVE(0x31000, 0x40000); + qoriq_pic pic; + QORIQ_FILL(0x40000, 0x80000, qoriq_pic); + QORIQ_RESERVE(0x80000, 0xb0000); + tsec_registers tsec_1_group_0; + QORIQ_FILL(0xb0000, 0xb1000, tsec_registers); + tsec_registers tsec_2_group_0; + QORIQ_FILL(0xb1000, 0xb2000, tsec_registers); + tsec_registers tsec_3_group_0; + QORIQ_FILL(0xb2000, 0xb3000, tsec_registers); + QORIQ_RESERVE(0xb3000, 0xb4000); + tsec_registers tsec_1_group_1; + QORIQ_FILL(0xb4000, 0xb5000, tsec_registers); + tsec_registers tsec_2_group_1; + QORIQ_FILL(0xb5000, 0xb6000, tsec_registers); + tsec_registers tsec_3_group_1; + QORIQ_FILL(0xb6000, 0xb7000, tsec_registers); + QORIQ_RESERVE(0xb7000, 0xc0000); + qoriq_serial_rapid_io serial_rapid_io; + QORIQ_FILL(0xc0000, 0xe0000, qoriq_serial_rapid_io); + qoriq_global_utilities global_utilities; + QORIQ_FILL(0xe0000, 0xe1000, qoriq_global_utilities); + qoriq_performance_monitor performance_monitor; + QORIQ_FILL(0xe1000, 0xe2000, qoriq_performance_monitor); + qoriq_debug_watchpoint debug_watchpoint; + QORIQ_FILL(0xe2000, 0xe3000, qoriq_debug_watchpoint); + qoriq_serdes serdes; + QORIQ_FILL(0xe3000, 0xe4000, qoriq_serdes); + QORIQ_RESERVE(0xe4000, 0xf0000); + qoriq_boot_rom boot_rom; + QORIQ_FILL(0xf0000, 0x100000, qoriq_boot_rom); +} qoriq_ccsr; + +#endif /* QORIQ_CHIP_VARIANT */ + +extern volatile qoriq_ccsr qoriq; + +#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) +extern uint8_t qoriq_bman_portal[2][16777216]; +extern uint8_t qoriq_qman_portal[2][16777216]; + +void qoriq_clear_ce_portal(void *base, size_t size); +void qoriq_clear_ci_portal(void *base, size_t size); +#endif + +static inline void qoriq_reset_qman_and_bman(void) +{ +#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) + qoriq.dcfg.qmbm_warmrst = 0x3; + + while ((qoriq.dcfg.qmbm_warmrst & 0x3) != 0) { + /* Wait for reset done */ + } +#endif +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_POWERPC_QORIQ_QORIQ_H */ diff --git a/bsps/powerpc/qoriq/include/bsp/tsec-config.h b/bsps/powerpc/qoriq/include/bsp/tsec-config.h new file mode 100644 index 0000000000..b1a70e7486 --- /dev/null +++ b/bsps/powerpc/qoriq/include/bsp/tsec-config.h @@ -0,0 +1,36 @@ +/** + * @file + * + * @ingroup QorIQ + * + * @brief TSEC configuration. + */ + +/* + * Copyright (c) 2010 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Obere Lagerstr. 30 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef LIBBSP_POWERPC_QORIQ_TSEC_CONFIG_H +#define LIBBSP_POWERPC_QORIQ_TSEC_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define TSEC_COUNT 3 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_POWERPC_QORIQ_TSEC_CONFIG_H */ diff --git a/bsps/powerpc/qoriq/include/bsp/uart-bridge.h b/bsps/powerpc/qoriq/include/bsp/uart-bridge.h new file mode 100644 index 0000000000..97e6553b7c --- /dev/null +++ b/bsps/powerpc/qoriq/include/bsp/uart-bridge.h @@ -0,0 +1,72 @@ +/** + * @file + * + * @ingroup QorIQUartBridge + * + * @brief UART to Intercom bridge API. + */ + +/* + * Copyright (c) 2011-2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef LIBBSP_POWERPC_QORIQ_UART_BRIDGE_H +#define LIBBSP_POWERPC_QORIQ_UART_BRIDGE_H + +#include <rtems/termiostypes.h> + +#include <bsp/intercom.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @defgroup QorIQUartBridge QorIQ - UART to Intercom Bridge Support + * + * @ingroup QorIQ + * + * @brief UART to Intercom bridge support. + * + * @{ + */ + +typedef struct { + rtems_termios_device_context base; + const char *device_path; + intercom_type type; + rtems_id transmit_task; + rtems_chain_control transmit_fifo; +} uart_bridge_master_context; + +typedef struct { + rtems_termios_device_context base; + struct rtems_termios_tty *tty; + intercom_type type; + rtems_id transmit_task; + rtems_chain_control transmit_fifo; +} uart_bridge_slave_context; + +bool qoriq_uart_bridge_master_probe(rtems_termios_device_context *base); + +extern const rtems_termios_device_handler qoriq_uart_bridge_master; + +extern const rtems_termios_device_handler qoriq_uart_bridge_slave; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* LIBBSP_POWERPC_QORIQ_UART_BRIDGE_H */ diff --git a/bsps/powerpc/qoriq/include/tm27.h b/bsps/powerpc/qoriq/include/tm27.h new file mode 100644 index 0000000000..46264b7e67 --- /dev/null +++ b/bsps/powerpc/qoriq/include/tm27.h @@ -0,0 +1,96 @@ +/** + * @file + * + * @ingroup QorIQ + * + * @brief Support file for Timer Test 27. + */ + +/* + * Copyright (c) 2010-2015 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * 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. + */ + +#ifndef _RTEMS_TMTEST27 + #error "This is an RTEMS internal file you must not include directly." +#endif /* _RTEMS_TMTEST27 */ + +#ifndef TMTESTS_TM27_H +#define TMTESTS_TM27_H + +#include <assert.h> + +#include <libcpu/powerpc-utility.h> + +#include <bsp/irq.h> +#include <bsp/qoriq.h> + +#define MUST_WAIT_FOR_INTERRUPT 1 + +#define IPI_INDEX_LOW 1 + +#define IPI_INDEX_HIGH 2 + +static void Install_tm27_vector(void (*handler)(rtems_vector_number)) +{ + rtems_status_code sc; + rtems_vector_number low = QORIQ_IRQ_IPI_0 + IPI_INDEX_LOW; + rtems_vector_number high = QORIQ_IRQ_IPI_0 + IPI_INDEX_HIGH; + + sc = rtems_interrupt_handler_install( + low, + "tm17 low", + RTEMS_INTERRUPT_UNIQUE, + (rtems_interrupt_handler) handler, + NULL + ); + assert(sc == RTEMS_SUCCESSFUL); + + sc = qoriq_pic_set_priority(low, 1, NULL); + assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_interrupt_handler_install( + high, + "tm17 high", + RTEMS_INTERRUPT_UNIQUE, + (rtems_interrupt_handler) handler, + NULL + ); + assert(sc == RTEMS_SUCCESSFUL); + + sc = qoriq_pic_set_priority(high, 2, NULL); + assert(sc == RTEMS_SUCCESSFUL); +} + +static void qoriq_tm27_cause(uint32_t ipi_index) +{ + uint32_t self = ppc_processor_id(); + + qoriq.pic.per_cpu[self].ipidr[ipi_index].reg = UINT32_C(1) << self; +} + +static void Cause_tm27_intr() +{ + qoriq_tm27_cause(IPI_INDEX_LOW); +} + +static void Clear_tm27_intr() +{ + /* Nothing to do */ +} + +static void Lower_tm27_intr(void) +{ + qoriq_tm27_cause(IPI_INDEX_HIGH); +} + +#endif /* TMTESTS_TM27_H */ diff --git a/bsps/powerpc/qoriq/include/uapi/asm/epapr_hcalls.h b/bsps/powerpc/qoriq/include/uapi/asm/epapr_hcalls.h new file mode 100644 index 0000000000..b4504f3944 --- /dev/null +++ b/bsps/powerpc/qoriq/include/uapi/asm/epapr_hcalls.h @@ -0,0 +1,98 @@ +/* + * ePAPR hcall interface + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. + * + * Author: Timur Tabi <timur@freescale.com> + * + * This file is provided under a dual BSD/GPL license. When using or + * redistributing this file, you may do so under either license. + * + * 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. + * * Neither the name of Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +#ifndef _UAPI_ASM_POWERPC_EPAPR_HCALLS_H +#define _UAPI_ASM_POWERPC_EPAPR_HCALLS_H + +#define EV_BYTE_CHANNEL_SEND 1 +#define EV_BYTE_CHANNEL_RECEIVE 2 +#define EV_BYTE_CHANNEL_POLL 3 +#define EV_INT_SET_CONFIG 4 +#define EV_INT_GET_CONFIG 5 +#define EV_INT_SET_MASK 6 +#define EV_INT_GET_MASK 7 +#define EV_INT_IACK 9 +#define EV_INT_EOI 10 +#define EV_INT_SEND_IPI 11 +#define EV_INT_SET_TASK_PRIORITY 12 +#define EV_INT_GET_TASK_PRIORITY 13 +#define EV_DOORBELL_SEND 14 +#define EV_MSGSND 15 +#define EV_IDLE 16 + +/* vendor ID: epapr */ +#define EV_LOCAL_VENDOR_ID 0 /* for private use */ +#define EV_EPAPR_VENDOR_ID 1 +#define EV_FSL_VENDOR_ID 2 /* Freescale Semiconductor */ +#define EV_IBM_VENDOR_ID 3 /* IBM */ +#define EV_GHS_VENDOR_ID 4 /* Green Hills Software */ +#define EV_ENEA_VENDOR_ID 5 /* Enea */ +#define EV_WR_VENDOR_ID 6 /* Wind River Systems */ +#define EV_AMCC_VENDOR_ID 7 /* Applied Micro Circuits */ +#define EV_KVM_VENDOR_ID 42 /* KVM */ + +/* The max number of bytes that a byte channel can send or receive per call */ +#define EV_BYTE_CHANNEL_MAX_BYTES 16 + + +#define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num)) +#define EV_HCALL_TOKEN(hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num) + +/* epapr return codes */ +#define EV_SUCCESS 0 +#define EV_EPERM 1 /* Operation not permitted */ +#define EV_ENOENT 2 /* Entry Not Found */ +#define EV_EIO 3 /* I/O error occurred */ +#define EV_EAGAIN 4 /* The operation had insufficient + * resources to complete and should be + * retried + */ +#define EV_ENOMEM 5 /* There was insufficient memory to + * complete the operation */ +#define EV_EFAULT 6 /* Bad guest address */ +#define EV_ENODEV 7 /* No such device */ +#define EV_EINVAL 8 /* An argument supplied to the hcall + was out of range or invalid */ +#define EV_INTERNAL 9 /* An internal error occurred */ +#define EV_CONFIG 10 /* A configuration error was detected */ +#define EV_INVALID_STATE 11 /* The object is in an invalid state */ +#define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ +#define EV_BUFFER_OVERFLOW 13 /* Caller-supplied buffer too small */ + +#endif /* _UAPI_ASM_POWERPC_EPAPR_HCALLS_H */ |