From 44a23cfd6360a68eaa41f945190618a55519eac3 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 16 Jan 2008 22:33:22 -0600 Subject: 85xx: Introduce new tlb API Add a set of functions to manipulate TLB entries: * set_tlb() - write a tlb entry * invalidate_tlb() - invalidate a tlb array * disable_tlb() - disable a variable size tlb entry * init_tlbs() - setup initial tlbs based on static table Signed-off-by: Kumar Gala --- cpu/mpc85xx/Makefile | 2 +- cpu/mpc85xx/spd_sdram.c | 16 ++------- cpu/mpc85xx/tlb.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ include/asm-ppc/mmu.h | 31 ++++++++++++++++ 4 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 cpu/mpc85xx/tlb.c diff --git a/cpu/mpc85xx/Makefile b/cpu/mpc85xx/Makefile index d179d70..2205dca 100644 --- a/cpu/mpc85xx/Makefile +++ b/cpu/mpc85xx/Makefile @@ -30,7 +30,7 @@ LIB = $(obj)lib$(CPU).a START = start.o resetvec.o COBJS-$(CONFIG_OF_LIBFDT) += fdt.o -COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \ +COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o tlb.o \ pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o qe_io.o \ $(COBJS-y) diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c index 90c3d44..abc63c4 100644 --- a/cpu/mpc85xx/spd_sdram.c +++ b/cpu/mpc85xx/spd_sdram.c @@ -1071,19 +1071,9 @@ setup_laws_and_tlbs(unsigned int memsize) ram_tlb_address = (unsigned int)CFG_DDR_SDRAM_BASE; while (ram_tlb_address < (memsize * 1024 * 1024) && ram_tlb_index < 16) { - mtspr(MAS0, FSL_BOOKE_MAS0(1, ram_tlb_index, 0)); - mtspr(MAS1, FSL_BOOKE_MAS1(1, 1, 0, 0, tlb_size)); - mtspr(MAS2, FSL_BOOKE_MAS2(ram_tlb_address, 0)); - mtspr(MAS3, FSL_BOOKE_MAS3(ram_tlb_address, 0, - (MAS3_SX|MAS3_SW|MAS3_SR))); - asm volatile("isync;msync;tlbwe;isync"); - - debug("DDR: MAS0=0x%08x\n", FSL_BOOKE_MAS0(1, ram_tlb_index, 0)); - debug("DDR: MAS1=0x%08x\n", FSL_BOOKE_MAS1(1, 1, 0, 0, tlb_size)); - debug("DDR: MAS2=0x%08x\n", FSL_BOOKE_MAS2(ram_tlb_address, 0)); - debug("DDR: MAS3=0x%08x\n", - FSL_BOOKE_MAS3(ram_tlb_address, 0, - (MAS3_SX|MAS3_SW|MAS3_SR))); + set_tlb(1, ram_tlb_address, ram_tlb_address, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 0, ram_tlb_index, tlb_size, 1); ram_tlb_address += (0x1000 << ((tlb_size - 1) * 2)); ram_tlb_index++; diff --git a/cpu/mpc85xx/tlb.c b/cpu/mpc85xx/tlb.c new file mode 100644 index 0000000..b319ad4 --- /dev/null +++ b/cpu/mpc85xx/tlb.c @@ -0,0 +1,95 @@ +/* + * Copyright 2008 Freescale Semiconductor, Inc. + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +void set_tlb(u8 tlb, u32 epn, u64 rpn, + u8 perms, u8 wimge, + u8 ts, u8 esel, u8 tsize, u8 iprot) +{ + u32 _mas0, _mas1, _mas2, _mas3, _mas7; + + _mas0 = FSL_BOOKE_MAS0(tlb, esel, 0); + _mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize); + _mas2 = FSL_BOOKE_MAS2(epn, wimge); + _mas3 = FSL_BOOKE_MAS3(rpn, 0, perms); + _mas7 = rpn >> 32; + + mtspr(MAS0, _mas0); + mtspr(MAS1, _mas1); + mtspr(MAS2, _mas2); + mtspr(MAS3, _mas3); +#ifdef CONFIG_ENABLE_36BIT_PHYS + mtspr(MAS7, _mas7); +#endif + asm volatile("isync;msync;tlbwe;isync"); +} + +void disable_tlb(u8 esel) +{ + u32 _mas0, _mas1, _mas2, _mas3, _mas7; + + _mas0 = FSL_BOOKE_MAS0(1, esel, 0); + _mas1 = 0; + _mas2 = 0; + _mas3 = 0; + _mas7 = 0; + + mtspr(MAS0, _mas0); + mtspr(MAS1, _mas1); + mtspr(MAS2, _mas2); + mtspr(MAS3, _mas3); +#ifdef CONFIG_ENABLE_36BIT_PHYS + mtspr(MAS7, _mas7); +#endif + asm volatile("isync;msync;tlbwe;isync"); +} + +void invalidate_tlb(u8 tlb) +{ + if (tlb == 0) + mtspr(MMUCSR0, 0x4); + if (tlb == 1) + mtspr(MMUCSR0, 0x2); +} + +void init_tlbs(void) +{ +#ifdef CONFIG_FSL_INIT_TLBS + int i; + + for (i = 0; i < num_tlb_entries; i++) { + set_tlb(tlb_table[i].tlb, tlb_table[i].epn, tlb_table[i].rpn, + tlb_table[i].perms, tlb_table[i].wimge, + tlb_table[i].ts, tlb_table[i].esel, tlb_table[i].tsize, + tlb_table[i].iprot); + } +#endif + + return ; +} + diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 45a4764..ec1ca53 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -418,6 +418,37 @@ extern int write_bat(ppc_bat_t bat, unsigned long upper, unsigned long lower); #define BOOKE_PAGESZ_256GB 14 #define BOOKE_PAGESZ_1TB 15 +#ifdef CONFIG_E500 +#ifndef __ASSEMBLY__ +extern void set_tlb(u8 tlb, u32 epn, u64 rpn, + u8 perms, u8 wimge, + u8 ts, u8 esel, u8 tsize, u8 iprot); +extern void disable_tlb(u8 esel); +extern void invalidate_tlb(u8 tlb); +extern void init_tlbs(void); + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define SET_TLB_ENTRY(_tlb, _epn, _rpn, _perms, _wimge, _ts, _esel, _sz, _iprot) \ + { .tlb = _tlb, .epn = _epn, .rpn = _rpn, .perms = _perms, \ + .wimge = _wimge, .ts = _ts, .esel = _esel, .tsize = _sz, .iprot = _iprot } + +struct fsl_e_tlb_entry { + u8 tlb; + u32 epn; + u64 rpn; + u8 perms; + u8 wimge; + u8 ts; + u8 esel; + u8 tsize; + u8 iprot; +}; + +extern struct fsl_e_tlb_entry tlb_table[]; +extern int num_tlb_entries; +#endif +#endif + #if defined(CONFIG_MPC86xx) #define LAWBAR_BASE_ADDR 0x00FFFFFF #define LAWAR_TRGT_IF 0x01F00000 -- cgit v1.1