1 /* 2 * Blackfin CPLB initialization 3 * 4 * Copyright 2008-2009 Analog Devices Inc. 5 * 6 * Licensed under the GPL-2 or later. 7 */ 8 9 #include <linux/module.h> 10 11 #include <asm/blackfin.h> 12 #include <asm/cplb.h> 13 #include <asm/cplbinit.h> 14 #include <asm/mem_map.h> 15 16 struct cplb_entry icplb_tbl[NR_CPUS][MAX_CPLBS]; 17 struct cplb_entry dcplb_tbl[NR_CPUS][MAX_CPLBS]; 18 19 int first_switched_icplb, first_switched_dcplb; 20 int first_mask_dcplb; 21 generate_cplb_tables_cpu(unsigned int cpu)22void __init generate_cplb_tables_cpu(unsigned int cpu) 23 { 24 int i_d, i_i; 25 unsigned long addr; 26 unsigned long d_data, i_data; 27 unsigned long d_cache = 0, i_cache = 0; 28 29 printk(KERN_INFO "MPU: setting up cplb tables with memory protection\n"); 30 31 #ifdef CONFIG_BFIN_EXTMEM_ICACHEABLE 32 i_cache = CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND; 33 #endif 34 35 #ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE 36 d_cache = CPLB_L1_CHBL; 37 #ifdef CONFIG_BFIN_EXTMEM_WRITETHROUGH 38 d_cache |= CPLB_L1_AOW | CPLB_WT; 39 #endif 40 #endif 41 42 i_d = i_i = 0; 43 44 /* Set up the zero page. */ 45 dcplb_tbl[cpu][i_d].addr = 0; 46 dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; 47 48 icplb_tbl[cpu][i_i].addr = 0; 49 icplb_tbl[cpu][i_i++].data = CPLB_VALID | i_cache | CPLB_USER_RD | PAGE_SIZE_1KB; 50 51 /* Cover kernel memory with 4M pages. */ 52 addr = 0; 53 d_data = d_cache | CPLB_SUPV_WR | CPLB_VALID | PAGE_SIZE_4MB | CPLB_DIRTY; 54 i_data = i_cache | CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4MB; 55 56 for (; addr < memory_start; addr += 4 * 1024 * 1024) { 57 dcplb_tbl[cpu][i_d].addr = addr; 58 dcplb_tbl[cpu][i_d++].data = d_data; 59 icplb_tbl[cpu][i_i].addr = addr; 60 icplb_tbl[cpu][i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0); 61 } 62 63 #ifdef CONFIG_ROMKERNEL 64 /* Cover kernel XIP flash area */ 65 addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1); 66 dcplb_tbl[cpu][i_d].addr = addr; 67 dcplb_tbl[cpu][i_d++].data = d_data | CPLB_USER_RD; 68 icplb_tbl[cpu][i_i].addr = addr; 69 icplb_tbl[cpu][i_i++].data = i_data | CPLB_USER_RD; 70 #endif 71 72 /* Cover L1 memory. One 4M area for code and data each is enough. */ 73 #if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0 74 dcplb_tbl[cpu][i_d].addr = get_l1_data_a_start_cpu(cpu); 75 dcplb_tbl[cpu][i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; 76 #endif 77 #if L1_CODE_LENGTH > 0 78 icplb_tbl[cpu][i_i].addr = get_l1_code_start_cpu(cpu); 79 icplb_tbl[cpu][i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; 80 #endif 81 82 /* Cover L2 memory */ 83 #if L2_LENGTH > 0 84 dcplb_tbl[cpu][i_d].addr = L2_START; 85 dcplb_tbl[cpu][i_d++].data = L2_DMEMORY; 86 icplb_tbl[cpu][i_i].addr = L2_START; 87 icplb_tbl[cpu][i_i++].data = L2_IMEMORY; 88 #endif 89 90 first_mask_dcplb = i_d; 91 first_switched_dcplb = i_d + (1 << page_mask_order); 92 first_switched_icplb = i_i; 93 94 while (i_d < MAX_CPLBS) 95 dcplb_tbl[cpu][i_d++].data = 0; 96 while (i_i < MAX_CPLBS) 97 icplb_tbl[cpu][i_i++].data = 0; 98 } 99 generate_cplb_tables_all(void)100void __init generate_cplb_tables_all(void) 101 { 102 } 103