Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 127023
b: refs/heads/master
c: b8a9898
h: refs/heads/master
i:
  127021: 79852d6
  127019: 08c7820
  127015: 6bf1b79
  127007: 1430dd0
v: v3
  • Loading branch information
Graf Yang authored and Bryan Wu committed Nov 18, 2008
1 parent 2fe4e35 commit 27dcb7f
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 220 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6b3087c64a92a36ae20d33479b4df6d7afc910d4
refs/heads/master: b8a989893cbdeb6c97a7b5af5f38fb0e480235f9
15 changes: 8 additions & 7 deletions trunk/arch/blackfin/include/asm/cplb-mpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
*/
#ifndef __ASM_BFIN_CPLB_MPU_H
#define __ASM_BFIN_CPLB_MPU_H
#include <linux/threads.h>

struct cplb_entry {
unsigned long data, addr;
Expand All @@ -39,22 +40,22 @@ struct mem_region {
unsigned long icplb_data;
};

extern struct cplb_entry dcplb_tbl[MAX_CPLBS];
extern struct cplb_entry icplb_tbl[MAX_CPLBS];
extern struct cplb_entry dcplb_tbl[NR_CPUS][MAX_CPLBS];
extern struct cplb_entry icplb_tbl[NR_CPUS][MAX_CPLBS];
extern int first_switched_icplb;
extern int first_mask_dcplb;
extern int first_switched_dcplb;

extern int nr_dcplb_miss, nr_icplb_miss, nr_icplb_supv_miss, nr_dcplb_prot;
extern int nr_cplb_flush;
extern int nr_dcplb_miss[], nr_icplb_miss[], nr_icplb_supv_miss[];
extern int nr_dcplb_prot[], nr_cplb_flush[];

extern int page_mask_order;
extern int page_mask_nelts;

extern unsigned long *current_rwx_mask;
extern unsigned long *current_rwx_mask[NR_CPUS];

extern void flush_switched_cplbs(void);
extern void set_mask_dcplbs(unsigned long *);
extern void flush_switched_cplbs(unsigned int);
extern void set_mask_dcplbs(unsigned long *, unsigned int);

extern void __noreturn panic_cplb_error(int seqstat, struct pt_regs *);

Expand Down
21 changes: 12 additions & 9 deletions trunk/arch/blackfin/include/asm/cplb.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#ifndef _CPLB_H
#define _CPLB_H

#include <asm/blackfin.h>
#include <mach/anomaly.h>

#define SDRAM_IGENERIC (CPLB_L1_CHBL | CPLB_USER_RD | CPLB_VALID | CPLB_PORTPRIO)
Expand All @@ -55,13 +54,24 @@
#endif

#define L1_DMEMORY (CPLB_LOCK | CPLB_COMMON)

#ifdef CONFIG_SMP
#define L2_ATTR (INITIAL_T | I_CPLB | D_CPLB)
#define L2_IMEMORY (CPLB_COMMON | CPLB_LOCK)
#define L2_DMEMORY (CPLB_COMMON | CPLB_LOCK)

#else
#ifdef CONFIG_BFIN_L2_CACHEABLE
#define L2_IMEMORY (SDRAM_IGENERIC)
#define L2_DMEMORY (SDRAM_DGENERIC)
#else
#define L2_IMEMORY (CPLB_COMMON)
#define L2_DMEMORY (CPLB_COMMON)
#endif
#endif /* CONFIG_BFIN_L2_CACHEABLE */

#define L2_ATTR (INITIAL_T | SWITCH_T | I_CPLB | D_CPLB)
#endif /* CONFIG_SMP */

#define SDRAM_DNON_CHBL (CPLB_COMMON)
#define SDRAM_EBIU (CPLB_COMMON)
#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
Expand All @@ -71,14 +81,7 @@
#define SIZE_1M 0x00100000 /* 1M */
#define SIZE_4M 0x00400000 /* 4M */

#ifdef CONFIG_MPU
#define MAX_CPLBS 16
#else
#define MAX_CPLBS (16 * 2)
#endif

#define ASYNC_MEMORY_CPLB_COVERAGE ((ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE) / SIZE_4M)

#define CPLB_ENABLE_ICACHE_P 0
#define CPLB_ENABLE_DCACHE_P 1
Expand Down
57 changes: 47 additions & 10 deletions trunk/arch/blackfin/include/asm/cplbinit.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#ifdef CONFIG_MPU

#include <asm/cplb-mpu.h>
extern void bfin_icache_init(struct cplb_entry *icplb_tbl);
extern void bfin_dcache_init(struct cplb_entry *icplb_tbl);

#else

Expand All @@ -46,8 +48,40 @@

#define IN_KERNEL 1

enum
{ZERO_P, L1I_MEM, L1D_MEM, SDRAM_KERN , SDRAM_RAM_MTD, SDRAM_DMAZ, RES_MEM, ASYNC_MEM, L2_MEM};
#define ASYNC_MEMORY_CPLB_COVERAGE ((ASYNC_BANK0_SIZE + ASYNC_BANK1_SIZE + \
ASYNC_BANK2_SIZE + ASYNC_BANK3_SIZE) / SIZE_4M)

#define CPLB_MEM CONFIG_MAX_MEM_SIZE

/*
* Number of required data CPLB switchtable entries
* MEMSIZE / 4 (we mostly install 4M page size CPLBs
* approx 16 for smaller 1MB page size CPLBs for allignment purposes
* 1 for L1 Data Memory
* possibly 1 for L2 Data Memory
* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
* 1 for ASYNC Memory
*/
#define MAX_SWITCH_D_CPLBS (((CPLB_MEM / 4) + 16 + 1 + 1 + 1 \
+ ASYNC_MEMORY_CPLB_COVERAGE) * 2)

/*
* Number of required instruction CPLB switchtable entries
* MEMSIZE / 4 (we mostly install 4M page size CPLBs
* approx 12 for smaller 1MB page size CPLBs for allignment purposes
* 1 for L1 Instruction Memory
* possibly 1 for L2 Instruction Memory
* 1 for CONFIG_DEBUG_HUNT_FOR_ZERO
*/
#define MAX_SWITCH_I_CPLBS (((CPLB_MEM / 4) + 12 + 1 + 1 + 1) * 2)

/* Number of CPLB table entries, used for cplb-nompu. */
#define CPLB_TBL_ENTRIES (16 * 4)

enum {
ZERO_P, L1I_MEM, L1D_MEM, L2_MEM, SDRAM_KERN, SDRAM_RAM_MTD, SDRAM_DMAZ,
RES_MEM, ASYNC_MEM, OCB_ROM
};

struct cplb_desc {
u32 start; /* start address */
Expand All @@ -66,8 +100,8 @@ struct cplb_tab {
u16 size;
};

extern u_long icplb_table[];
extern u_long dcplb_table[];
extern u_long icplb_tables[NR_CPUS][CPLB_TBL_ENTRIES+1];
extern u_long dcplb_tables[NR_CPUS][CPLB_TBL_ENTRIES+1];

/* Till here we are discussing about the static memory management model.
* However, the operating envoronments commonly define more CPLB
Expand All @@ -78,15 +112,18 @@ extern u_long dcplb_table[];
* This is how Page descriptor Table is implemented in uClinux/Blackfin.
*/

extern u_long ipdt_table[];
extern u_long dpdt_table[];
extern u_long ipdt_tables[NR_CPUS][MAX_SWITCH_I_CPLBS+1];
extern u_long dpdt_tables[NR_CPUS][MAX_SWITCH_D_CPLBS+1];
#ifdef CONFIG_CPLB_INFO
extern u_long ipdt_swapcount_table[];
extern u_long dpdt_swapcount_table[];
extern u_long ipdt_swapcount_tables[NR_CPUS][MAX_SWITCH_I_CPLBS];
extern u_long dpdt_swapcount_tables[NR_CPUS][MAX_SWITCH_D_CPLBS];
#endif
extern void bfin_icache_init(u_long icplbs[]);
extern void bfin_dcache_init(u_long dcplbs[]);

#endif /* CONFIG_MPU */

extern void generate_cplb_tables(void);

#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE)
extern void generate_cplb_tables_cpu(unsigned int cpu);
#endif
#endif
27 changes: 19 additions & 8 deletions trunk/arch/blackfin/include/asm/mmu_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
#include <asm/pgalloc.h>
#include <asm/cplbinit.h>

/* Note: L1 stacks are CPU-private things, so we bluntly disable this
feature in SMP mode, and use the per-CPU scratch SRAM bank only to
store the PDA instead. */

extern void *current_l1_stack_save;
extern int nr_l1stack_tasks;
extern void *l1_stack_base;
Expand Down Expand Up @@ -88,12 +92,15 @@ activate_l1stack(struct mm_struct *mm, unsigned long sp_base)
static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
struct task_struct *tsk)
{
#ifdef CONFIG_MPU
unsigned int cpu = smp_processor_id();
#endif
if (prev_mm == next_mm)
return;
#ifdef CONFIG_MPU
if (prev_mm->context.page_rwx_mask == current_rwx_mask) {
flush_switched_cplbs();
set_mask_dcplbs(next_mm->context.page_rwx_mask);
if (prev_mm->context.page_rwx_mask == current_rwx_mask[cpu]) {
flush_switched_cplbs(cpu);
set_mask_dcplbs(next_mm->context.page_rwx_mask, cpu);
}
#endif

Expand Down Expand Up @@ -138,9 +145,10 @@ static inline void protect_page(struct mm_struct *mm, unsigned long addr,

static inline void update_protections(struct mm_struct *mm)
{
if (mm->context.page_rwx_mask == current_rwx_mask) {
flush_switched_cplbs();
set_mask_dcplbs(mm->context.page_rwx_mask);
unsigned int cpu = smp_processor_id();
if (mm->context.page_rwx_mask == current_rwx_mask[cpu]) {
flush_switched_cplbs(cpu);
set_mask_dcplbs(mm->context.page_rwx_mask, cpu);
}
}
#endif
Expand All @@ -165,6 +173,9 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm)
static inline void destroy_context(struct mm_struct *mm)
{
struct sram_list_struct *tmp;
#ifdef CONFIG_MPU
unsigned int cpu = smp_processor_id();
#endif

#ifdef CONFIG_APP_STACK_L1
if (current_l1_stack_save == mm->context.l1_stack_save)
Expand All @@ -179,8 +190,8 @@ static inline void destroy_context(struct mm_struct *mm)
kfree(tmp);
}
#ifdef CONFIG_MPU
if (current_rwx_mask == mm->context.page_rwx_mask)
current_rwx_mask = NULL;
if (current_rwx_mask[cpu] == mm->context.page_rwx_mask)
current_rwx_mask[cpu] = NULL;
free_pages((unsigned long)mm->context.page_rwx_mask, page_mask_order);
#endif
}
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/blackfin/kernel/cplb-mpu/cacheinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <asm/cplbinit.h>

#if defined(CONFIG_BFIN_ICACHE)
void __init bfin_icache_init(void)
void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
{
unsigned long ctrl;
int i;
Expand All @@ -43,7 +43,7 @@ void __init bfin_icache_init(void)
#endif

#if defined(CONFIG_BFIN_DCACHE)
void __init bfin_dcache_init(void)
void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
{
unsigned long ctrl;
int i;
Expand Down
43 changes: 28 additions & 15 deletions trunk/arch/blackfin/kernel/cplb-mpu/cplbinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,32 +66,32 @@ static char *cplb_print_entry(char *buf, struct cplb_entry *tbl, int switched)
return buf;
}

int cplbinfo_proc_output(char *buf)
int cplbinfo_proc_output(char *buf, void *data)
{
char *p;
unsigned int cpu = (unsigned int)data;;

p = buf;

p += sprintf(p, "------------------ CPLB Information ------------------\n\n");

p += sprintf(p, "------------- CPLB Information on CPU%u --------------\n\n", cpu);
if (bfin_read_IMEM_CONTROL() & ENICPLB) {
p += sprintf(p, "Instruction CPLB entry:\n");
p = cplb_print_entry(p, icplb_tbl, first_switched_icplb);
p = cplb_print_entry(p, icplb_tbl[cpu], first_switched_icplb);
} else
p += sprintf(p, "Instruction CPLB is disabled.\n\n");

if (1 || bfin_read_DMEM_CONTROL() & ENDCPLB) {
p += sprintf(p, "Data CPLB entry:\n");
p = cplb_print_entry(p, dcplb_tbl, first_switched_dcplb);
p = cplb_print_entry(p, dcplb_tbl[cpu], first_switched_dcplb);
} else
p += sprintf(p, "Data CPLB is disabled.\n");

p += sprintf(p, "ICPLB miss: %d\nICPLB supervisor miss: %d\n",
nr_icplb_miss, nr_icplb_supv_miss);
nr_icplb_miss[cpu], nr_icplb_supv_miss[cpu]);
p += sprintf(p, "DCPLB miss: %d\nDCPLB protection fault:%d\n",
nr_dcplb_miss, nr_dcplb_prot);
nr_dcplb_miss[cpu], nr_dcplb_prot[cpu]);
p += sprintf(p, "CPLB flushes: %d\n",
nr_cplb_flush);
nr_cplb_flush[cpu]);

return p - buf;
}
Expand All @@ -101,7 +101,7 @@ static int cplbinfo_read_proc(char *page, char **start, off_t off,
{
int len;

len = cplbinfo_proc_output(page);
len = cplbinfo_proc_output(page, data);
if (len <= off + count)
*eof = 1;
*start = page + off;
Expand All @@ -115,20 +115,33 @@ static int cplbinfo_read_proc(char *page, char **start, off_t off,

static int __init cplbinfo_init(void)
{
struct proc_dir_entry *entry;
struct proc_dir_entry *parent, *entry;
unsigned int cpu;
unsigned char str[10];

parent = proc_mkdir("cplbinfo", NULL);

entry = create_proc_entry("cplbinfo", 0, NULL);
if (!entry)
return -ENOMEM;
for_each_online_cpu(cpu) {
sprintf(str, "cpu%u", cpu);
entry = create_proc_entry(str, 0, parent);
if (!entry)
return -ENOMEM;

entry->read_proc = cplbinfo_read_proc;
entry->data = NULL;
entry->read_proc = cplbinfo_read_proc;
entry->data = (void *)cpu;
}

return 0;
}

static void __exit cplbinfo_exit(void)
{
unsigned int cpu;
unsigned char str[20];
for_each_online_cpu(cpu) {
sprintf(str, "cplbinfo/cpu%u", cpu);
remove_proc_entry(str, NULL);
}
remove_proc_entry("cplbinfo", NULL);
}

Expand Down
Loading

0 comments on commit 27dcb7f

Please sign in to comment.