-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Blackfin] arch: Initial checkin of the memory protection support.
Enable it with CONFIG_MPU. Signed-off-by: Bernd Schmidt <bernd.schmidt@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
- Loading branch information
Bernd Schmidt
authored and
Bryan Wu
committed
Jan 27, 2008
1 parent
2047e40
commit b97b8a9
Showing
15 changed files
with
822 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# | ||
# arch/blackfin/kernel/cplb-nompu/Makefile | ||
# | ||
|
||
obj-y := cplbinit.o cacheinit.o cplbmgr.o | ||
|
||
obj-$(CONFIG_CPLB_INFO) += cplbinfo.o | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Copyright 2004-2007 Analog Devices Inc. | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, see the file COPYING, or write | ||
* to the Free Software Foundation, Inc., | ||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
#include <linux/cpu.h> | ||
|
||
#include <asm/cacheflush.h> | ||
#include <asm/blackfin.h> | ||
#include <asm/cplb.h> | ||
#include <asm/cplbinit.h> | ||
|
||
#if defined(CONFIG_BFIN_ICACHE) | ||
void bfin_icache_init(void) | ||
{ | ||
unsigned long ctrl; | ||
int i; | ||
|
||
SSYNC(); | ||
for (i = 0; i < MAX_CPLBS; i++) { | ||
bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr); | ||
bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data); | ||
} | ||
ctrl = bfin_read_IMEM_CONTROL(); | ||
ctrl |= IMC | ENICPLB; | ||
bfin_write_IMEM_CONTROL(ctrl); | ||
SSYNC(); | ||
} | ||
#endif | ||
|
||
#if defined(CONFIG_BFIN_DCACHE) | ||
void bfin_dcache_init(void) | ||
{ | ||
unsigned long ctrl; | ||
int i; | ||
|
||
SSYNC(); | ||
for (i = 0; i < MAX_CPLBS; i++) { | ||
bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr); | ||
bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data); | ||
} | ||
|
||
ctrl = bfin_read_DMEM_CONTROL(); | ||
ctrl |= DMEM_CNTR; | ||
bfin_write_DMEM_CONTROL(ctrl); | ||
SSYNC(); | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* File: arch/blackfin/mach-common/cplbinfo.c | ||
* Based on: | ||
* Author: Sonic Zhang <sonic.zhang@analog.com> | ||
* | ||
* Created: Jan. 2005 | ||
* Description: Display CPLB status | ||
* | ||
* Modified: | ||
* Copyright 2004-2006 Analog Devices Inc. | ||
* | ||
* Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, see the file COPYING, or write | ||
* to the Free Software Foundation, Inc., | ||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/kernel.h> | ||
#include <linux/init.h> | ||
#include <linux/proc_fs.h> | ||
#include <linux/uaccess.h> | ||
|
||
#include <asm/current.h> | ||
#include <asm/system.h> | ||
#include <asm/cplb.h> | ||
#include <asm/cplbinit.h> | ||
#include <asm/blackfin.h> | ||
|
||
#define CPLB_I 1 | ||
#define CPLB_D 2 | ||
|
||
#define SYNC_SYS SSYNC() | ||
#define SYNC_CORE CSYNC() | ||
|
||
#define CPLB_BIT_PAGESIZE 0x30000 | ||
|
||
static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" }; | ||
|
||
static char *cplb_print_entry(char *buf, struct cplb_entry *tbl, int switched) | ||
{ | ||
int i; | ||
buf += sprintf(buf, "Index\tAddress\t\tData\tSize\tU/RD\tU/WR\tS/WR\tSwitch\n"); | ||
for (i = 0; i < MAX_CPLBS; i++) { | ||
unsigned long data = tbl[i].data; | ||
unsigned long addr = tbl[i].addr; | ||
if (!(data & CPLB_VALID)) | ||
continue; | ||
|
||
buf += | ||
sprintf(buf, | ||
"%d\t0x%08lx\t%06lx\t%s\t%c\t%c\t%c\t%c\n", | ||
i, addr, data, | ||
page_size_string_table[(data & 0x30000) >> 16], | ||
(data & CPLB_USER_RD) ? 'Y' : 'N', | ||
(data & CPLB_USER_WR) ? 'Y' : 'N', | ||
(data & CPLB_SUPV_WR) ? 'Y' : 'N', | ||
i < switched ? 'N' : 'Y'); | ||
} | ||
buf += sprintf(buf, "\n"); | ||
|
||
return buf; | ||
} | ||
|
||
int cplbinfo_proc_output(char *buf) | ||
{ | ||
char *p; | ||
|
||
p = buf; | ||
|
||
p += sprintf(p, "------------------ CPLB Information ------------------\n\n"); | ||
|
||
if (bfin_read_IMEM_CONTROL() & ENICPLB) { | ||
p += sprintf(p, "Instruction CPLB entry:\n"); | ||
p = cplb_print_entry(p, icplb_tbl, 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); | ||
} 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); | ||
p += sprintf(p, "DCPLB miss: %d\nDCPLB protection fault:%d\n", | ||
nr_dcplb_miss, nr_dcplb_prot); | ||
p += sprintf(p, "CPLB flushes: %d\n", | ||
nr_cplb_flush); | ||
|
||
return p - buf; | ||
} | ||
|
||
static int cplbinfo_read_proc(char *page, char **start, off_t off, | ||
int count, int *eof, void *data) | ||
{ | ||
int len; | ||
|
||
len = cplbinfo_proc_output(page); | ||
if (len <= off + count) | ||
*eof = 1; | ||
*start = page + off; | ||
len -= off; | ||
if (len > count) | ||
len = count; | ||
if (len < 0) | ||
len = 0; | ||
return len; | ||
} | ||
|
||
static int __init cplbinfo_init(void) | ||
{ | ||
struct proc_dir_entry *entry; | ||
|
||
entry = create_proc_entry("cplbinfo", 0, NULL); | ||
if (!entry) | ||
return -ENOMEM; | ||
|
||
entry->read_proc = cplbinfo_read_proc; | ||
entry->data = NULL; | ||
|
||
return 0; | ||
} | ||
|
||
static void __exit cplbinfo_exit(void) | ||
{ | ||
remove_proc_entry("cplbinfo", NULL); | ||
} | ||
|
||
module_init(cplbinfo_init); | ||
module_exit(cplbinfo_exit); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Blackfin CPLB initialization | ||
* | ||
* Copyright 2004-2007 Analog Devices Inc. | ||
* | ||
* Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, see the file COPYING, or write | ||
* to the Free Software Foundation, Inc., | ||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
*/ | ||
#include <linux/module.h> | ||
|
||
#include <asm/blackfin.h> | ||
#include <asm/cplb.h> | ||
#include <asm/cplbinit.h> | ||
|
||
struct cplb_entry icplb_tbl[MAX_CPLBS]; | ||
struct cplb_entry dcplb_tbl[MAX_CPLBS]; | ||
|
||
int first_switched_icplb, first_switched_dcplb; | ||
int first_mask_dcplb; | ||
|
||
void __init generate_cpl_tables(void) | ||
{ | ||
int i_d, i_i; | ||
unsigned long addr; | ||
unsigned long d_data, i_data; | ||
unsigned long d_cache = 0, i_cache = 0; | ||
|
||
#ifdef CONFIG_BFIN_ICACHE | ||
i_cache = CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND; | ||
#endif | ||
|
||
#ifdef CONFIG_BFIN_DCACHE | ||
d_cache = CPLB_L1_CHBL; | ||
#ifdef CONFIG_BLKFIN_WT | ||
d_cache |= CPLB_L1_AOW | CPLB_WT; | ||
#endif | ||
#endif | ||
i_d = i_i = 0; | ||
|
||
/* Set up the zero page. */ | ||
dcplb_tbl[i_d].addr = 0; | ||
dcplb_tbl[i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; | ||
|
||
#if 0 | ||
icplb_tbl[i_i].addr = 0; | ||
icplb_tbl[i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB; | ||
#endif | ||
|
||
/* Cover kernel memory with 4M pages. */ | ||
addr = 0; | ||
d_data = d_cache | CPLB_SUPV_WR | CPLB_VALID | PAGE_SIZE_4MB | CPLB_DIRTY; | ||
i_data = i_cache | CPLB_VALID | CPLB_PORTPRIO | PAGE_SIZE_4MB; | ||
|
||
for (; addr < memory_start; addr += 4 * 1024 * 1024) { | ||
dcplb_tbl[i_d].addr = addr; | ||
dcplb_tbl[i_d++].data = d_data; | ||
icplb_tbl[i_i].addr = addr; | ||
icplb_tbl[i_i++].data = i_data | (addr == 0 ? CPLB_USER_RD : 0); | ||
} | ||
|
||
/* Cover L1 memory. One 4M area for code and data each is enough. */ | ||
#if L1_DATA_A_LENGTH > 0 || L1_DATA_B_LENGTH > 0 | ||
dcplb_tbl[i_d].addr = L1_DATA_A_START; | ||
dcplb_tbl[i_d++].data = L1_DMEMORY | PAGE_SIZE_4MB; | ||
#endif | ||
icplb_tbl[i_i].addr = L1_CODE_START; | ||
icplb_tbl[i_i++].data = L1_IMEMORY | PAGE_SIZE_4MB; | ||
|
||
first_mask_dcplb = i_d; | ||
first_switched_dcplb = i_d + (1 << page_mask_order); | ||
first_switched_icplb = i_i; | ||
|
||
while (i_d < MAX_CPLBS) | ||
dcplb_tbl[i_d++].data = 0; | ||
while (i_i < MAX_CPLBS) | ||
icplb_tbl[i_i++].data = 0; | ||
} |
Oops, something went wrong.