-Added support for physical addresses larger than virtual ones, handled

via architecture-specific paddr_t
-Fix type-punning for asid_manager_t
This commit is contained in:
Jan Stoess 2010-07-14 12:05:40 +02:00
parent b6f9ba493f
commit 919fd029ee
15 changed files with 58 additions and 54 deletions

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2004, Karlsruhe University
* Copyright (C) 2004, 2010, Karlsruhe University
*
* File path: kdb/generic/bootinfo.cc
* Description: Generic bootinfo dumping
@ -164,7 +164,7 @@ class bootinfo_t
word_t __reserved[3];
word_t safe_get (word_t * fld)
{ return kdb.kdb_current->get_space ()->readmem_phys (fld); }
{ return kdb.kdb_current->get_space ()->readmem_phys ((paddr_t)fld); }
public:
@ -243,7 +243,7 @@ CMD (cmd_dump_bootinfo, cg)
word_t * src = (word_t *) bi;
word_t * dst = (word_t *) bootinfo_copy;
for (;size > 0; size -= sizeof (word_t), src++, dst++)
*dst = s->readmem_phys (src);
*dst = s->readmem_phys ((paddr_t) src);
bi = bootinfo_copy;
}

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2002-2004, 2007-2008, Karlsruhe University
* Copyright (C) 2002-2004, 2007-2008, 2010, Karlsruhe University
*
* File path: kdb/generic/linear_ptab_dump.cc
* Description: Linear page table dump
@ -130,7 +130,7 @@ CMD(cmd_dump_ptab, cg)
// Print valid mapping
word_t pgsz = page_size (size);
word_t rwx = pg->reference_bits (space, size, vaddr);
printf ("%p [%p]:%s phys=%p map=%p %s%3d%cB %c%c%c "
printf ("%p [%p]:%s phys=%X map=%p %s%3d%cB %c%c%c "
"(%c%c%c) %s ",
vaddr, pg->raw, spcptr, pg->address (space, size),
pg->mapnode (space, size, vaddr), spcpad,

View File

@ -151,6 +151,7 @@ int SECTION(SEC_KDEBUG) print_string(const char * s,
for (;;)
{
ASSERT(s);
if (*s == 0)
break;

View File

@ -3,7 +3,7 @@
* Copyright (C) 1999-2010, Karlsruhe University
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
*
* File path: src/arch/powerpc/types.h
* File path: arch/powerpc/types.h
* Description:
*
* Redistribution and use in source and binary forms, with or without
@ -61,6 +61,17 @@ typedef u64_t paddr_t;
typedef u32_t paddr_t;
#endif
INLINE paddr_t addr_offset(paddr_t addr, word_t off)
{
return (paddr_t)(addr + off);
}
INLINE paddr_t addr_mask (paddr_t addr, word_t mask)
{
return (paddr_t) (addr & mask);
}
/**
* Counts the number of zeros starting at the msb (bit 31).

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2003, National ICT Australia (NICTA)
* Copyright (C) 2003, 2010, National ICT Australia (NICTA)
*
* File path: arch/powerpc64/types.h
* Description: PowerPC64 specific types
@ -52,4 +52,10 @@ typedef signed char s8_t;
*/
typedef u64_t word_t;
/**
* paddr_t - used to denote physical addresses
*/
typedef void * paddr_t;
#endif /* !__ARCH__POWERPC64__TYPES_H__ */

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2007, Karlsruhe University
* Copyright (C) 2007, 2010, Karlsruhe University
*
* File path: arch/x86/types.h
* Description:
@ -15,4 +15,9 @@
#include INC_ARCH_SA(types.h)
/**
* paddr_t - used to denote physical addresses
*/
typedef void * paddr_t;
#endif /* !__ARCH__X86__TYPES_H__ */

View File

@ -96,7 +96,8 @@ public:
void free_asid(word_t asid)
{
list_entry[asid] = free_list;
free_list = (word_t *) &list_entry[asid];
word_t **fl = &list_entry[asid];
free_list = (word_t *) fl;
}
void allocate_asid(T* space)
@ -130,14 +131,13 @@ public:
return asid->asid;
}
public:
private:
word_t *free_list;
union {
T* asid_user[SIZE];
word_t *list_entry[SIZE];
};
private:
word_t start, end;
word_t timestamp;
};

View File

@ -105,7 +105,7 @@ void space_t::map_fpage (fpage_t snd_fp, word_t base,
pgent_t::pgsize_e f_size, t_size, pgsize;
mapnode_t *newmap, *map = NULL;
addr_t f_addr, t_addr;
pgent_t * r_fpg[pgent_t::size_max];
pgent_t * r_tpg[pgent_t::size_max];
word_t r_fnum[pgent_t::size_max];
@ -436,9 +436,8 @@ void space_t::map_fpage (fpage_t snd_fp, word_t base,
/* Check if we're simply extending access rights */
(tpg->is_subtree (t_space, t_size) ||
(is_sigma0_space (this) ?
(tpg->address (t_space, t_size) != f_addr) :
(tpg->address (t_space, t_size) !=
fpg->address (this, f_size)))
(tpg->address (t_space, t_size) != (paddr_t) f_addr) :
(tpg->address (t_space, t_size) != fpg->address (this, f_size)))
#if defined(CONFIG_NEW_MDB)
||
(tpg->mapnode (t_space, t_size,
@ -582,11 +581,11 @@ void space_t::map_fpage (fpage_t snd_fp, word_t base,
* just extending the current access rights.
*/
if (is_sigma0_space (this) ?
(tpg->address (t_space, t_size) != f_addr) :
(tpg->address (t_space, t_size) != (paddr_t) f_addr) :
(tpg->address (t_space, t_size) !=
addr_offset (fpg->address (this, f_size), offset)))
{
addr_t a UNUSED = is_sigma0_space (this) ? f_addr :
paddr_t a UNUSED = is_sigma0_space (this) ? (paddr_t) f_addr :
addr_offset (fpg->address (this, f_size), offset);
printf ("map_fpage(from=%p to=%p base=%p "
"sndfp=%p rcvfp=%p) paddr %p != %p\n",
@ -669,7 +668,7 @@ void space_t::map_fpage (fpage_t snd_fp, word_t base,
"pg=%p addr=%p %d%cB}) paddr=%p\n", map,
fpg, f_addr, dbg_pgsize (page_size(f_size)), dbg_szname (page_size(f_size)),
tpg, t_addr, dbg_pgsize (page_size(t_size)), dbg_szname (page_size(t_size)),
addr_offset (fpg->address (this, f_size), offset + f_off));
(addr_t) addr_offset (fpg->address (this, f_size), offset + f_off));
#endif
#if defined(CONFIG_NEW_MDB)
@ -989,9 +988,9 @@ bool space_t::readmem (addr_t vaddr, word_t * contents)
if (! lookup_mapping (vaddr, &pg, &pgsize))
return false;
addr_t paddr = pg->address (this, pgsize);
paddr_t paddr = pg->address (this, pgsize);
paddr = addr_offset (paddr, (word_t) vaddr & page_mask (pgsize));
addr_t paddr1 = addr_mask (paddr, ~(sizeof (word_t) - 1));
paddr_t paddr1 = addr_mask (paddr, ~(sizeof (word_t) - 1));
if (paddr1 == paddr)
{
@ -1002,7 +1001,7 @@ bool space_t::readmem (addr_t vaddr, word_t * contents)
{
// Word access not properly aligned. Need to perform two
// separate accesses.
addr_t paddr2 = addr_offset (paddr1, sizeof (word_t));
paddr_t paddr2 = addr_offset (paddr1, sizeof (word_t));
word_t mask = ~page_mask (pgsize);
if (addr_mask (paddr1, mask) != addr_mask (paddr2, mask))

View File

@ -1,6 +1,6 @@
/*********************************************************************
*
* Copyright (C) 2005-2007, Karlsruhe University
* Copyright (C) 2005-2007, 2010, Karlsruhe University
*
* File path: generic/mdb_mem.cc
* Description: Memory specific generic mapping database functions
@ -286,7 +286,7 @@ word_t mdb_mem_t::get_purged_status (mdb_node_t * node)
return purged_status (node);
}
/**
/*
* Reset the purged status bits for mapping.
* @param node mapping node
*/

View File

@ -3,7 +3,7 @@
* Copyright (C) 1999-2010, Karlsruhe University
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
*
* File path: src/glue/v4-powerpc/pgent-swtlb.h
* File path: glue/v4-powerpc/pgent-swtlb.h
* Description:
*
* Redistribution and use in source and binary forms, with or without
@ -104,8 +104,7 @@ public:
// Retrieval
addr_t address( space_t * s, pgsize_e pgsize );
paddr_t paddress( space_t *s, pgsize_e pgsize );
paddr_t address( space_t * s, pgsize_e pgsize );
pgent_t * subtree( space_t * s, pgsize_e pgsize );
mapnode_t * mapnode( space_t * s, pgsize_e pgsize, addr_t vaddr );
addr_t vaddr( space_t * s, pgsize_e pgsize, mapnode_t * map );
@ -121,8 +120,6 @@ public:
void remove_subtree( space_t * s, pgsize_e pgsize, bool kernel );
void set_entry( space_t * s, pgsize_e pgsize, paddr_t paddr,
word_t rwx, word_t attrib, bool kernel );
void set_entry( space_t * s, pgsize_e pgsize, addr_t paddr,
word_t rwx, word_t attrib, bool kernel );
void set_writable( space_t * s, pgsize_e pgsize );
void set_readonly( space_t * s, pgsize_e pgsize );
void update_rights( space_t *s, pgsize_e pgsize, word_t rwx );

View File

@ -3,7 +3,7 @@
* Copyright (C) 1999-2010, Karlsruhe University
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
*
* File path: src/glue/v4-powerpc/pgent-swtlb_inline.h
* File path: glue/v4-powerpc/pgent-swtlb_inline.h
* Description:
*
* Redistribution and use in source and binary forms, with or without
@ -84,14 +84,7 @@ inline bool pgent_t::is_kernel( space_t * s, pgsize_e pgsize )
}
// Retrieval
inline addr_t pgent_t::address( space_t * s, pgsize_e pgsize )
{
// ASSERT(this->map.erpn == 0);
return (addr_t)(this->raw & POWERPC_PAGE_MASK);
}
inline paddr_t pgent_t::paddress( space_t * s, pgsize_e pgsize )
inline paddr_t pgent_t::address( space_t * s, pgsize_e pgsize )
{
return (paddr_t)(this->raw & POWERPC_PAGE_MASK) +
((paddr_t)this->map.erpn << 32);
@ -172,7 +165,7 @@ inline void pgent_t::make_subtree( space_t * s, pgsize_e pgsize, bool kernel )
inline void pgent_t::remove_subtree( space_t * s, pgsize_e pgsize, bool kernel )
{
addr_t ptab = this->address( s, pgsize );
addr_t ptab = (addr_t) this->address( s, pgsize );
this->raw = 0;
kmem.free( kmem_pgtab, ptab, POWERPC_PAGE_SIZE * (kernel ? 1:2) );
@ -189,12 +182,6 @@ inline void pgent_t::set_entry( space_t * s, pgsize_e pgsize, paddr_t paddr,
this->map.caching = attrib;
}
inline void pgent_t::set_entry( space_t * s, pgsize_e pgsize, addr_t paddr,
word_t rwx, word_t attrib, bool kernel )
{
set_entry(s, pgsize, (paddr_t)paddr, rwx, attrib,! kernel);
}
inline void pgent_t::update_rights( space_t *s, pgsize_e pgsize, word_t rwx )
{
@ -254,8 +241,6 @@ inline pgent_t * pgent_t::next( space_t * s, pgsize_e pgsize, word_t num )
inline void pgent_t::dump_misc (space_t * s, pgsize_e pgsize)
{
if (map.erpn != 0)
printf("erpn: %x ", map.erpn);
printf("%s",
map.caching == 1 ? "inhibit " :
map.caching == 2 ? "coherent " :

View File

@ -3,7 +3,7 @@
* Copyright (C) 1999-2010, Karlsruhe University
* Copyright (C) 2008-2009, Volkmar Uhlig, IBM Corporation
*
* File path: src/glue/v4-powerpc/pgent.h
* File path: glue/v4-powerpc/pgent.h
* Description:
*
* Redistribution and use in source and binary forms, with or without
@ -123,7 +123,7 @@ public:
inline void clear( space_t * s, pgsize_e pgsize, bool kernel, addr_t vaddr);
inline void make_subtree( space_t * s, pgsize_e pgsize, bool kernel );
inline void remove_subtree( space_t * s, pgsize_e pgsize, bool kernel );
inline void set_entry( space_t * s, pgsize_e pgsize, addr_t paddr,
inline void set_entry( space_t * s, pgsize_e pgsize, paddr_t paddr,
word_t rwx, word_t attrib, bool kernel );
inline void set_writable( space_t * s, pgsize_e pgsize );
inline void set_readonly( space_t * s, pgsize_e pgsize );

View File

@ -201,7 +201,7 @@ NOINLINE bool space_t::handle_tlb_miss( addr_t lookup_vaddr, addr_t install_vadd
size_t size = page_shift (pgsize);
word_t vaddr = (word_t) install_vaddr;
paddr_t paddr = pg->paddress (this, pgsize) | (vaddr & ((1ul << size) - 1));
paddr_t paddr = pg->address (this, pgsize) | (vaddr & ((1ul << size) - 1));
while (!ppc_tlb0_t::is_valid_pagesize (size))
size--;

View File

@ -255,12 +255,12 @@ found:
**********************************************************************/
void space_t::release_kernel_mapping (addr_t vaddr, addr_t paddr,
void space_t::release_kernel_mapping (addr_t vaddr, paddr_t paddr,
word_t log2size)
{
// Free up memory used for UTCBs
if (get_utcb_page_area ().is_addr_in_fpage (vaddr))
kmem.free (kmem_utcb, phys_to_virt (paddr), 1UL << log2size);
kmem.free (kmem_utcb, (addr_t) phys_to_virt (paddr), 1UL << log2size);
}
utcb_t *space_t::allocate_utcb( tcb_t *tcb )
@ -272,7 +272,7 @@ utcb_t *space_t::allocate_utcb( tcb_t *tcb )
pgent_t *pgent = this->page_lookup( utcb );
if( pgent && pgent->is_valid(this, pgent_t::size_4k) )
// Already a valid page mapped at the UTCB address.
page = phys_to_virt( pgent->address(this, pgent_t::size_4k) );
page = (addr_t) phys_to_virt( pgent->address(this, pgent_t::size_4k) );
else
{
// Allocate a new UTCB page.

View File

@ -174,9 +174,9 @@ public:
bool lookup_mapping( addr_t vaddr, pgent_t ** r_pg,
pgent_t::pgsize_e *r_size, cpuid_t cpu = 0);
bool readmem (addr_t vaddr, word_t * contents);
static word_t readmem_phys (addr_t paddr)
static word_t readmem_phys (paddr_t paddr)
{ return *phys_to_virt((word_t*)paddr); }
void release_kernel_mapping (addr_t vaddr, addr_t paddr, word_t log2size);
void release_kernel_mapping (addr_t vaddr, paddr_t paddr, word_t log2size);
static space_t *vsid_to_space( word_t vsid )
{