cregit-Linux how code gets into the kernel

Release 4.14 arch/blackfin/kernel/cplb-nompu/cplbmgr.c

/*
 * Based on:     arch/blackfin/kernel/cplb-mpu/cplbmgr.c
 * Author:       Michael McTernan <mmcternan@airvana.com>
 *
 * Description:  CPLB miss handler.
 *
 * Modified:
 *               Copyright 2008 Airvana Inc.
 *               Copyright 2008-2009 Analog Devices Inc.
 *
 * Licensed under the GPL-2 or later
 */

#include <linux/kernel.h>
#include <asm/blackfin.h>
#include <asm/cplbinit.h>
#include <asm/cplb.h>
#include <asm/mmu_context.h>
#include <asm/traps.h>

/*
 * WARNING
 *
 * This file is compiled with certain -ffixed-reg options.  We have to
 * make sure not to call any functions here that could clobber these
 * registers.
 */



int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS];


int nr_dcplb_supv_miss[NR_CPUS], nr_icplb_supv_miss[NR_CPUS];


int nr_cplb_flush[NR_CPUS], nr_dcplb_prot[NR_CPUS];

#ifdef CONFIG_EXCPT_IRQ_SYSC_L1

#define MGR_ATTR __attribute__((l1_text))
#else

#define MGR_ATTR
#endif


static inline void write_dcplb_data(int cpu, int idx, unsigned long data, unsigned long addr) { _disable_dcplb(); bfin_write32(DCPLB_DATA0 + idx * 4, data); bfin_write32(DCPLB_ADDR0 + idx * 4, addr); _enable_dcplb(); #ifdef CONFIG_CPLB_INFO dcplb_tbl[cpu][idx].addr = addr; dcplb_tbl[cpu][idx].data = data; #endif }

Contributors

PersonTokensPropCommitsCommitProp
Bernd Schmidt7596.15%150.00%
Yi Li33.85%150.00%
Total78100.00%2100.00%


static inline void write_icplb_data(int cpu, int idx, unsigned long data, unsigned long addr) { _disable_icplb(); bfin_write32(ICPLB_DATA0 + idx * 4, data); bfin_write32(ICPLB_ADDR0 + idx * 4, addr); _enable_icplb(); #ifdef CONFIG_CPLB_INFO icplb_tbl[cpu][idx].addr = addr; icplb_tbl[cpu][idx].data = data; #endif }

Contributors

PersonTokensPropCommitsCommitProp
Bernd Schmidt7596.15%150.00%
Yi Li33.85%150.00%
Total78100.00%2100.00%

/* Counters to implement round-robin replacement. */ static int icplb_rr_index[NR_CPUS] PDT_ATTR; static int dcplb_rr_index[NR_CPUS] PDT_ATTR; /* * Find an ICPLB entry to be evicted and return its index. */
static int evict_one_icplb(int cpu) { int i = first_switched_icplb + icplb_rr_index[cpu]; if (i >= MAX_CPLBS) { i -= MAX_CPLBS - first_switched_icplb; icplb_rr_index[cpu] -= MAX_CPLBS - first_switched_icplb; } icplb_rr_index[cpu]++; return i; }

Contributors

PersonTokensPropCommitsCommitProp
Bernd Schmidt51100.00%1100.00%
Total51100.00%1100.00%


static int evict_one_dcplb(int cpu) { int i = first_switched_dcplb + dcplb_rr_index[cpu]; if (i >= MAX_CPLBS) { i -= MAX_CPLBS - first_switched_dcplb; dcplb_rr_index[cpu] -= MAX_CPLBS - first_switched_dcplb; } dcplb_rr_index[cpu]++; return i; }

Contributors

PersonTokensPropCommitsCommitProp
Bernd Schmidt51100.00%1100.00%
Total51100.00%1100.00%


MGR_ATTR static int icplb_miss(int cpu) { unsigned long addr = bfin_read_ICPLB_FAULT_ADDR(); int status = bfin_read_ICPLB_STATUS(); int idx; unsigned long i_data, base, addr1, eaddr; nr_icplb_miss[cpu]++; if (unlikely(status & FAULT_USERSUPV)) nr_icplb_supv_miss[cpu]++; base = 0; idx = 0; do { eaddr = icplb_bounds[idx].eaddr; if (addr < eaddr) break; base = eaddr; } while (++idx < icplb_nr_bounds); if (unlikely(idx == icplb_nr_bounds)) return CPLB_NO_ADDR_MATCH; i_data = icplb_bounds[idx].data; if (unlikely(i_data == 0)) return CPLB_NO_ADDR_MATCH; addr1 = addr & ~(SIZE_4M - 1); addr &= ~(SIZE_1M - 1); i_data |= PAGE_SIZE_1MB; if (addr1 >= base && (addr1 + SIZE_4M) <= eaddr) { /* * This works because * (PAGE_SIZE_4MB & PAGE_SIZE_1MB) == PAGE_SIZE_1MB. */ i_data |= PAGE_SIZE_4MB; addr = addr1; } /* Pick entry to evict */ idx = evict_one_icplb(cpu); write_icplb_data(cpu, idx, i_data, addr); return CPLB_RELOADED; }

Contributors

PersonTokensPropCommitsCommitProp
Bernd Schmidt19095.00%150.00%
Mike Frysinger105.00%150.00%
Total200100.00%2100.00%


MGR_ATTR static int dcplb_miss(int cpu) { unsigned long addr = bfin_read_DCPLB_FAULT_ADDR(); int status = bfin_read_DCPLB_STATUS(); int idx; unsigned long d_data, base, addr1, eaddr, cplb_pagesize, cplb_pageflags; nr_dcplb_miss[cpu]++; if (unlikely(status & FAULT_USERSUPV)) nr_dcplb_supv_miss[cpu]++; base = 0; idx = 0; do { eaddr = dcplb_bounds[idx].eaddr; if (addr < eaddr) break; base = eaddr; } while (++idx < dcplb_nr_bounds); if (unlikely(idx == dcplb_nr_bounds)) return CPLB_NO_ADDR_MATCH; d_data = dcplb_bounds[idx].data; if (unlikely(d_data == 0)) return CPLB_NO_ADDR_MATCH; addr &= ~(SIZE_1M - 1); d_data |= PAGE_SIZE_1MB; /* BF60x support large than 4M CPLB page size */ #ifdef PAGE_SIZE_16MB cplb_pageflags = PAGE_SIZE_16MB; cplb_pagesize = SIZE_16M; #else cplb_pageflags = PAGE_SIZE_4MB; cplb_pagesize = SIZE_4M; #endif find_pagesize: addr1 = addr & ~(cplb_pagesize - 1); if (addr1 >= base && (addr1 + cplb_pagesize) <= eaddr) { /* * This works because * (PAGE_SIZE_4MB & PAGE_SIZE_1MB) == PAGE_SIZE_1MB. */ d_data |= cplb_pageflags; addr = addr1; goto found_pagesize; } else { if (cplb_pagesize > SIZE_4M) { cplb_pageflags = PAGE_SIZE_4MB; cplb_pagesize = SIZE_4M; goto find_pagesize; } } found_pagesize: #ifdef CONFIG_BF60x if ((addr >= ASYNC_BANK0_BASE) && (addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE)) d_data |= PAGE_SIZE_64MB; #endif /* Pick entry to evict */ idx = evict_one_dcplb(cpu); write_dcplb_data(cpu, idx, d_data, addr); return CPLB_RELOADED; }

Contributors

PersonTokensPropCommitsCommitProp
Bernd Schmidt17863.12%125.00%
Steven Miao6924.47%125.00%
Bob Liu258.87%125.00%
Mike Frysinger103.55%125.00%
Total282100.00%4100.00%


MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs) { int cause = seqstat & 0x3f; unsigned int cpu = raw_smp_processor_id(); switch (cause) { case VEC_CPLB_I_M: return icplb_miss(cpu); case VEC_CPLB_M: return dcplb_miss(cpu); default: return CPLB_UNKNOWN_ERR; } }

Contributors

PersonTokensPropCommitsCommitProp
Bernd Schmidt5394.64%133.33%
Robin Getz23.57%133.33%
Yi Li11.79%133.33%
Total56100.00%3100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Bernd Schmidt75485.58%112.50%
Steven Miao697.83%112.50%
Bob Liu252.84%112.50%
Mike Frysinger202.27%112.50%
Yi Li70.79%225.00%
Robin Getz60.68%225.00%
Total881100.00%8100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.