mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 06:31:31 +00:00
[ppc4xx] Extend program_tlb() with virtual & physical addresses
Now program_tlb() allows to program a TLB (or multiple) with different virtual and physical addresses. With this change, now one physical region (e.g. SDRAM) can be mapped 2 times, once with caches diabled and once with caches enabled. Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
parent
fba3fb0449
commit
dbca208518
3 changed files with 48 additions and 37 deletions
|
@ -262,7 +262,7 @@ typedef struct bank_param BANKPARMS;
|
|||
#ifdef CFG_SIMULATE_SPD_EEPROM
|
||||
extern unsigned char cfg_simulate_spd_eeprom[128];
|
||||
#endif
|
||||
void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
|
||||
void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
|
||||
|
||||
static unsigned char spd_read(uchar chip, uint addr);
|
||||
static void get_spd_info(unsigned long *dimm_populated,
|
||||
|
@ -373,7 +373,7 @@ long int spd_sdram(void) {
|
|||
|
||||
#ifdef CONFIG_PROG_SDRAM_TLB /* this define should eventually be removed */
|
||||
/* and program tlb entries for this size (dynamic) */
|
||||
program_tlb(0, total_size, MY_TLB_WORD2_I_ENABLE);
|
||||
program_tlb(0, 0, total_size, MY_TLB_WORD2_I_ENABLE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -144,7 +144,7 @@ typedef enum ddr_cas_id {
|
|||
* Prototypes
|
||||
*-----------------------------------------------------------------------------*/
|
||||
static unsigned long sdram_memsize(void);
|
||||
void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
|
||||
void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value);
|
||||
static void get_spd_info(unsigned long *dimm_populated,
|
||||
unsigned char *iic0_dimm_addr,
|
||||
unsigned long num_dimm_banks);
|
||||
|
@ -528,7 +528,7 @@ long int initdram(int board_type)
|
|||
dram_size = sdram_memsize();
|
||||
|
||||
/* and program tlb entries for this size (dynamic) */
|
||||
program_tlb(0, dram_size, MY_TLB_WORD2_I_ENABLE);
|
||||
program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE);
|
||||
|
||||
/*------------------------------------------------------------------
|
||||
* DQS calibration.
|
||||
|
|
|
@ -36,7 +36,8 @@ typedef struct region {
|
|||
unsigned long tlb_word2_i_value;
|
||||
} region_t;
|
||||
|
||||
static int add_tlb_entry(unsigned long base_addr,
|
||||
static int add_tlb_entry(unsigned long phys_addr,
|
||||
unsigned long virt_addr,
|
||||
unsigned long tlb_word0_size_value,
|
||||
unsigned long tlb_word2_i_value)
|
||||
{
|
||||
|
@ -55,9 +56,9 @@ static int add_tlb_entry(unsigned long base_addr,
|
|||
return -1;
|
||||
|
||||
/* Second, create the TLB entry */
|
||||
tlb_word0_value = TLB_WORD0_EPN_ENCODE(base_addr) | TLB_WORD0_V_ENABLE |
|
||||
tlb_word0_value = TLB_WORD0_EPN_ENCODE(virt_addr) | TLB_WORD0_V_ENABLE |
|
||||
TLB_WORD0_TS_0 | tlb_word0_size_value;
|
||||
tlb_word1_value = TLB_WORD1_RPN_ENCODE(base_addr) | TLB_WORD1_ERPN_ENCODE(0);
|
||||
tlb_word1_value = TLB_WORD1_RPN_ENCODE(phys_addr) | TLB_WORD1_ERPN_ENCODE(0);
|
||||
tlb_word2_value = TLB_WORD2_U0_DISABLE | TLB_WORD2_U1_DISABLE |
|
||||
TLB_WORD2_U2_DISABLE | TLB_WORD2_U3_DISABLE |
|
||||
TLB_WORD2_W_DISABLE | tlb_word2_i_value |
|
||||
|
@ -81,7 +82,9 @@ static int add_tlb_entry(unsigned long base_addr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
|
||||
static void program_tlb_addr(unsigned long phys_addr,
|
||||
unsigned long virt_addr,
|
||||
unsigned long mem_size,
|
||||
unsigned long tlb_word2_i_value)
|
||||
{
|
||||
int rc;
|
||||
|
@ -91,70 +94,78 @@ static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
|
|||
while (mem_size != 0) {
|
||||
rc = 0;
|
||||
/* Add the TLB entries in to map the region. */
|
||||
if (((base_addr & TLB_256MB_ALIGN_MASK) == base_addr) &&
|
||||
if (((phys_addr & TLB_256MB_ALIGN_MASK) == phys_addr) &&
|
||||
(mem_size >= TLB_256MB_SIZE)) {
|
||||
/* Add a 256MB TLB entry */
|
||||
if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256MB, tlb_i)) == 0) {
|
||||
if ((rc = add_tlb_entry(phys_addr, virt_addr,
|
||||
TLB_WORD0_SIZE_256MB, tlb_i)) == 0) {
|
||||
mem_size -= TLB_256MB_SIZE;
|
||||
base_addr += TLB_256MB_SIZE;
|
||||
phys_addr += TLB_256MB_SIZE;
|
||||
}
|
||||
} else if (((base_addr & TLB_16MB_ALIGN_MASK) == base_addr) &&
|
||||
} else if (((phys_addr & TLB_16MB_ALIGN_MASK) == phys_addr) &&
|
||||
(mem_size >= TLB_16MB_SIZE)) {
|
||||
/* Add a 16MB TLB entry */
|
||||
if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16MB, tlb_i)) == 0) {
|
||||
if ((rc = add_tlb_entry(phys_addr, virt_addr,
|
||||
TLB_WORD0_SIZE_16MB, tlb_i)) == 0) {
|
||||
mem_size -= TLB_16MB_SIZE;
|
||||
base_addr += TLB_16MB_SIZE;
|
||||
phys_addr += TLB_16MB_SIZE;
|
||||
}
|
||||
} else if (((base_addr & TLB_1MB_ALIGN_MASK) == base_addr) &&
|
||||
} else if (((phys_addr & TLB_1MB_ALIGN_MASK) == phys_addr) &&
|
||||
(mem_size >= TLB_1MB_SIZE)) {
|
||||
/* Add a 1MB TLB entry */
|
||||
if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1MB, tlb_i)) == 0) {
|
||||
if ((rc = add_tlb_entry(phys_addr, virt_addr,
|
||||
TLB_WORD0_SIZE_1MB, tlb_i)) == 0) {
|
||||
mem_size -= TLB_1MB_SIZE;
|
||||
base_addr += TLB_1MB_SIZE;
|
||||
phys_addr += TLB_1MB_SIZE;
|
||||
}
|
||||
} else if (((base_addr & TLB_256KB_ALIGN_MASK) == base_addr) &&
|
||||
} else if (((phys_addr & TLB_256KB_ALIGN_MASK) == phys_addr) &&
|
||||
(mem_size >= TLB_256KB_SIZE)) {
|
||||
/* Add a 256KB TLB entry */
|
||||
if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_256KB, tlb_i)) == 0) {
|
||||
if ((rc = add_tlb_entry(phys_addr, virt_addr,
|
||||
TLB_WORD0_SIZE_256KB, tlb_i)) == 0) {
|
||||
mem_size -= TLB_256KB_SIZE;
|
||||
base_addr += TLB_256KB_SIZE;
|
||||
phys_addr += TLB_256KB_SIZE;
|
||||
}
|
||||
} else if (((base_addr & TLB_64KB_ALIGN_MASK) == base_addr) &&
|
||||
} else if (((phys_addr & TLB_64KB_ALIGN_MASK) == phys_addr) &&
|
||||
(mem_size >= TLB_64KB_SIZE)) {
|
||||
/* Add a 64KB TLB entry */
|
||||
if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_64KB, tlb_i)) == 0) {
|
||||
if ((rc = add_tlb_entry(phys_addr, virt_addr,
|
||||
TLB_WORD0_SIZE_64KB, tlb_i)) == 0) {
|
||||
mem_size -= TLB_64KB_SIZE;
|
||||
base_addr += TLB_64KB_SIZE;
|
||||
phys_addr += TLB_64KB_SIZE;
|
||||
}
|
||||
} else if (((base_addr & TLB_16KB_ALIGN_MASK) == base_addr) &&
|
||||
} else if (((phys_addr & TLB_16KB_ALIGN_MASK) == phys_addr) &&
|
||||
(mem_size >= TLB_16KB_SIZE)) {
|
||||
/* Add a 16KB TLB entry */
|
||||
if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_16KB, tlb_i)) == 0) {
|
||||
if ((rc = add_tlb_entry(phys_addr, virt_addr,
|
||||
TLB_WORD0_SIZE_16KB, tlb_i)) == 0) {
|
||||
mem_size -= TLB_16KB_SIZE;
|
||||
base_addr += TLB_16KB_SIZE;
|
||||
phys_addr += TLB_16KB_SIZE;
|
||||
}
|
||||
} else if (((base_addr & TLB_4KB_ALIGN_MASK) == base_addr) &&
|
||||
} else if (((phys_addr & TLB_4KB_ALIGN_MASK) == phys_addr) &&
|
||||
(mem_size >= TLB_4KB_SIZE)) {
|
||||
/* Add a 4KB TLB entry */
|
||||
if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_4KB, tlb_i)) == 0) {
|
||||
if ((rc = add_tlb_entry(phys_addr, virt_addr,
|
||||
TLB_WORD0_SIZE_4KB, tlb_i)) == 0) {
|
||||
mem_size -= TLB_4KB_SIZE;
|
||||
base_addr += TLB_4KB_SIZE;
|
||||
phys_addr += TLB_4KB_SIZE;
|
||||
}
|
||||
} else if (((base_addr & TLB_1KB_ALIGN_MASK) == base_addr) &&
|
||||
} else if (((phys_addr & TLB_1KB_ALIGN_MASK) == phys_addr) &&
|
||||
(mem_size >= TLB_1KB_SIZE)) {
|
||||
/* Add a 1KB TLB entry */
|
||||
if ((rc = add_tlb_entry(base_addr, TLB_WORD0_SIZE_1KB, tlb_i)) == 0) {
|
||||
if ((rc = add_tlb_entry(phys_addr, virt_addr,
|
||||
TLB_WORD0_SIZE_1KB, tlb_i)) == 0) {
|
||||
mem_size -= TLB_1KB_SIZE;
|
||||
base_addr += TLB_1KB_SIZE;
|
||||
phys_addr += TLB_1KB_SIZE;
|
||||
}
|
||||
} else {
|
||||
printf("ERROR: no TLB size exists for the base address 0x%0X.\n",
|
||||
base_addr);
|
||||
phys_addr);
|
||||
}
|
||||
|
||||
if (rc != 0)
|
||||
printf("ERROR: no TLB entries available for the base addr 0x%0X.\n",
|
||||
base_addr);
|
||||
phys_addr);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -166,16 +177,16 @@ static void program_tlb_addr(unsigned long base_addr, unsigned long mem_size,
|
|||
* Common usage for boards with SDRAM DIMM modules to dynamically
|
||||
* configure the TLB's for the SDRAM
|
||||
*/
|
||||
void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value)
|
||||
void program_tlb(u32 phys_addr, u32 virt_addr, u32 size, u32 tlb_word2_i_value)
|
||||
{
|
||||
region_t region_array;
|
||||
|
||||
region_array.base = start;
|
||||
region_array.base = phys_addr;
|
||||
region_array.size = size;
|
||||
region_array.tlb_word2_i_value = tlb_word2_i_value; /* en-/disable cache */
|
||||
|
||||
/* Call the routine to add in the tlb entries for the memory regions */
|
||||
program_tlb_addr(region_array.base, region_array.size,
|
||||
program_tlb_addr(region_array.base, virt_addr, region_array.size,
|
||||
region_array.tlb_word2_i_value);
|
||||
|
||||
return;
|
||||
|
|
Loading…
Add table
Reference in a new issue