Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: bcm281xx: Add L2 cache enable code

- Adds a module to provide calls into secure monitor mode
- Uses this module to make secure monitor calls to enable L2 cache.

Updates from V1:
- Split DT portion into separate patch
- replace #ifdef-ed L2 code with "if".
- move init call to board init

Signed-off-by: Christian Daudt <csd@broadcom.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>

+265 -1
+3 -1
arch/arm/mach-bcm/Makefile
··· 10 10 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 11 # GNU General Public License for more details. 12 12 13 - obj-$(CONFIG_ARCH_BCM) := board_bcm.o 13 + obj-$(CONFIG_ARCH_BCM) := board_bcm.o bcm_kona_smc.o bcm_kona_smc_asm.o 14 + plus_sec := $(call as-instr,.arch_extension sec,+sec) 15 + AFLAGS_bcm_kona_smc_asm.o :=-Wa,-march=armv7-a$(plus_sec)
+118
arch/arm/mach-bcm/bcm_kona_smc.c
··· 1 + /* 2 + * Copyright (C) 2013 Broadcom Corporation 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License as 6 + * published by the Free Software Foundation version 2. 7 + * 8 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 + * kind, whether express or implied; without even the implied warranty 10 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <stdarg.h> 15 + #include <linux/smp.h> 16 + #include <linux/io.h> 17 + #include <linux/ioport.h> 18 + 19 + #include <asm/cacheflush.h> 20 + #include <linux/of_address.h> 21 + 22 + #include "bcm_kona_smc.h" 23 + 24 + struct secure_bridge_data { 25 + void __iomem *bounce; /* virtual address */ 26 + u32 __iomem buffer_addr; /* physical address */ 27 + int initialized; 28 + } bridge_data; 29 + 30 + struct bcm_kona_smc_data { 31 + unsigned service_id; 32 + unsigned arg0; 33 + unsigned arg1; 34 + unsigned arg2; 35 + unsigned arg3; 36 + }; 37 + 38 + static const struct of_device_id bcm_kona_smc_ids[] __initconst = { 39 + {.compatible = "bcm,kona-smc"}, 40 + {}, 41 + }; 42 + 43 + /* Map in the bounce area */ 44 + void bcm_kona_smc_init(void) 45 + { 46 + struct device_node *node; 47 + 48 + /* Read buffer addr and size from the device tree node */ 49 + node = of_find_matching_node(NULL, bcm_kona_smc_ids); 50 + BUG_ON(!node); 51 + 52 + /* Don't care about size or flags of the DT node */ 53 + bridge_data.buffer_addr = 54 + be32_to_cpu(*of_get_address(node, 0, NULL, NULL)); 55 + BUG_ON(!bridge_data.buffer_addr); 56 + 57 + bridge_data.bounce = of_iomap(node, 0); 58 + BUG_ON(!bridge_data.bounce); 59 + 60 + bridge_data.initialized = 1; 61 + 62 + pr_info("Secure API initialized!\n"); 63 + } 64 + 65 + /* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */ 66 + static void __bcm_kona_smc(void *info) 67 + { 68 + struct bcm_kona_smc_data *data = info; 69 + u32 *args = bridge_data.bounce; 70 + int rc = 0; 71 + 72 + /* Must run on CPU 0 */ 73 + BUG_ON(smp_processor_id() != 0); 74 + 75 + /* Check map in the bounce area */ 76 + BUG_ON(!bridge_data.initialized); 77 + 78 + /* Copy one 32 bit word into the bounce area */ 79 + args[0] = data->arg0; 80 + args[1] = data->arg1; 81 + args[2] = data->arg2; 82 + args[3] = data->arg3; 83 + 84 + /* Flush caches for input data passed to Secure Monitor */ 85 + if (data->service_id != SSAPI_BRCM_START_VC_CORE) 86 + flush_cache_all(); 87 + 88 + /* Trap into Secure Monitor */ 89 + rc = bcm_kona_smc_asm(data->service_id, bridge_data.buffer_addr); 90 + 91 + if (rc != SEC_ROM_RET_OK) 92 + pr_err("Secure Monitor call failed (0x%x)!\n", rc); 93 + } 94 + 95 + unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1, 96 + unsigned arg2, unsigned arg3) 97 + { 98 + struct bcm_kona_smc_data data; 99 + 100 + data.service_id = service_id; 101 + data.arg0 = arg0; 102 + data.arg1 = arg1; 103 + data.arg2 = arg2; 104 + data.arg3 = arg3; 105 + 106 + /* 107 + * Due to a limitation of the secure monitor, we must use the SMP 108 + * infrastructure to forward all secure monitor calls to Core 0. 109 + */ 110 + if (get_cpu() != 0) 111 + smp_call_function_single(0, __bcm_kona_smc, (void *)&data, 1); 112 + else 113 + __bcm_kona_smc(&data); 114 + 115 + put_cpu(); 116 + 117 + return 0; 118 + }
+80
arch/arm/mach-bcm/bcm_kona_smc.h
··· 1 + /* 2 + * Copyright (C) 2013 Broadcom Corporation 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License as 6 + * published by the Free Software Foundation version 2. 7 + * 8 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 + * kind, whether express or implied; without even the implied warranty 10 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #ifndef BCM_KONA_SMC_H 15 + #define BCM_KONA_SMC_H 16 + 17 + #include <linux/types.h> 18 + #define FLAGS (SEC_ROM_ICACHE_ENABLE_MASK | SEC_ROM_DCACHE_ENABLE_MASK | \ 19 + SEC_ROM_IRQ_ENABLE_MASK | SEC_ROM_FIQ_ENABLE_MASK) 20 + 21 + /*! 22 + * Definitions for IRQ & FIQ Mask for ARM 23 + */ 24 + 25 + #define FIQ_IRQ_MASK 0xC0 26 + #define FIQ_MASK 0x40 27 + #define IRQ_MASK 0x80 28 + 29 + /*! 30 + * Secure Mode FLAGs 31 + */ 32 + 33 + /* When set, enables ICache within the secure mode */ 34 + #define SEC_ROM_ICACHE_ENABLE_MASK 0x00000001 35 + 36 + /* When set, enables DCache within the secure mode */ 37 + #define SEC_ROM_DCACHE_ENABLE_MASK 0x00000002 38 + 39 + /* When set, enables IRQ within the secure mode */ 40 + #define SEC_ROM_IRQ_ENABLE_MASK 0x00000004 41 + 42 + /* When set, enables FIQ within the secure mode */ 43 + #define SEC_ROM_FIQ_ENABLE_MASK 0x00000008 44 + 45 + /* When set, enables Unified L2 cache within the secure mode */ 46 + #define SEC_ROM_UL2_CACHE_ENABLE_MASK 0x00000010 47 + 48 + /* Broadcom Secure Service API Service IDs */ 49 + #define SSAPI_DORMANT_ENTRY_SERV 0x01000000 50 + #define SSAPI_PUBLIC_OTP_SERV 0x01000001 51 + #define SSAPI_ENABLE_L2_CACHE 0x01000002 52 + #define SSAPI_DISABLE_L2_CACHE 0x01000003 53 + #define SSAPI_WRITE_SCU_STATUS 0x01000004 54 + #define SSAPI_WRITE_PWR_GATE 0x01000005 55 + 56 + /* Broadcom Secure Service API Return Codes */ 57 + #define SEC_ROM_RET_OK 0x00000001 58 + #define SEC_ROM_RET_FAIL 0x00000009 59 + 60 + #define SSAPI_RET_FROM_INT_SERV 0x4 61 + #define SEC_EXIT_NORMAL 0x1 62 + 63 + #define SSAPI_ROW_AES 0x0E000006 64 + #define SSAPI_BRCM_START_VC_CORE 0x0E000008 65 + 66 + #ifndef __ASSEMBLY__ 67 + extern void bcm_kona_smc_init(void); 68 + 69 + extern unsigned bcm_kona_smc(unsigned service_id, 70 + unsigned arg0, 71 + unsigned arg1, 72 + unsigned arg2, 73 + unsigned arg3); 74 + 75 + extern int bcm_kona_smc_asm(u32 service_id, 76 + u32 buffer_addr); 77 + 78 + #endif /* __ASSEMBLY__ */ 79 + 80 + #endif /* BCM_KONA_SMC_H */
+41
arch/arm/mach-bcm/bcm_kona_smc_asm.S
··· 1 + /* 2 + * Copyright (C) 2013 Broadcom Corporation 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public License as 6 + * published by the Free Software Foundation version 2. 7 + * 8 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9 + * kind, whether express or implied; without even the implied warranty 10 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <linux/linkage.h> 15 + #include "bcm_kona_smc.h" 16 + 17 + /* 18 + * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr) 19 + */ 20 + 21 + ENTRY(bcm_kona_smc_asm) 22 + stmfd sp!, {r4-r12, lr} 23 + mov r4, r0 @ service_id 24 + mov r5, #3 @ Keep IRQ and FIQ off in SM 25 + /* 26 + * Since interrupts are disabled in the open mode, we must keep 27 + * interrupts disabled in secure mode by setting R5=0x3. If interrupts 28 + * are enabled in open mode, we can set R5=0x0 to allow interrupts in 29 + * secure mode. If we did this, the secure monitor would return back 30 + * control to the open mode to handle the interrupt prior to completing 31 + * the secure service. If this happened, R12 would not be 32 + * SEC_EXIT_NORMAL and we would need to call SMC again after resetting 33 + * R5 (it gets clobbered by the secure monitor) and setting R4 to 34 + * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor 35 + * to finish up the previous uncompleted secure service. 36 + */ 37 + mov r6, r1 @ buffer_addr 38 + smc #0 39 + /* Check r12 for SEC_EXIT_NORMAL here if interrupts are enabled */ 40 + ldmfd sp!, {r4-r12, pc} 41 + ENDPROC(bcm_kona_smc_asm)
+23
arch/arm/mach-bcm/board_bcm.c
··· 19 19 20 20 #include <asm/mach/arch.h> 21 21 #include <asm/mach/time.h> 22 + #include <asm/hardware/cache-l2x0.h> 22 23 23 24 static void timer_init(void) 24 25 { 25 26 } 26 27 27 28 29 + #include "bcm_kona_smc.h" 30 + 31 + static int __init kona_l2_cache_init(void) 32 + { 33 + if (!IS_ENABLED(CONFIG_CACHE_L2X0)) 34 + return 0; 35 + 36 + bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0); 37 + 38 + /* 39 + * The aux_val and aux_mask have no effect since L2 cache is already 40 + * enabled. Pass 0s for aux_val and 1s for aux_mask for default value. 41 + */ 42 + l2x0_of_init(0, ~0); 43 + 44 + return 0; 45 + } 46 + 28 47 static void __init board_init(void) 29 48 { 30 49 of_platform_populate(NULL, of_default_bus_match_table, NULL, 31 50 &platform_bus); 51 + 52 + bcm_kona_smc_init(); 53 + 54 + kona_l2_cache_init(); 32 55 } 33 56 34 57 static const char * const bcm11351_dt_compat[] = { "bcm,bcm11351", NULL, };