Introduce extended mappings, allowing to map memory addresses longer than 32 bits on 32 bit systems. For PowerPC, everything above 32 bits is mapped cache-inhibited.

This commit is contained in:
Jens Kehne 2010-12-02 15:40:13 +01:00
parent 6af04051e9
commit 83bcba646e
26 changed files with 283 additions and 85 deletions

View File

@ -382,7 +382,7 @@ SYS_SPACE_CONTROL (threadid_t space_tid, word_t control, fpage_t kip_area,
}
}
word_t old_control = space->space_control (control);
word_t old_control = space->space_control (control, kip_area, utcb_area, redirector_tid);
return_space_control (1, old_control);

View File

@ -245,7 +245,7 @@ public:
#endif
}
void set_entry (space_t * s, pgsize_e pgsize, addr_t paddr,
void set_entry (space_t * s, pgsize_e pgsize, paddr_t paddr,
word_t rwx, word_t attrib, bool kernel)
{
pgent.set_entry (paddr,

View File

@ -653,10 +653,11 @@ void space_t::map_fpage (fpage_t snd_fp, word_t base,
false);
else
#endif
tpg->set_entry (t_space, t_size,
sigma0_translate(addr_offset (f_addr, offset + f_off), f_size),
paddr_t paddr = sigma0_translate (addr_offset(f_addr, offset + f_off), f_size);
tpg->set_entry (t_space, t_size,
paddr,
snd_fp.get_rwx (),
sigma0_attributes(fpg, addr_offset(f_addr, offset + f_off), f_size),
sigma0_attributes(fpg, paddr, f_size),
false);
tpg->set_linknode (t_space, t_size, newmap, t_addr);
}

View File

@ -108,21 +108,30 @@ bool space_t::sync_kernel_space(addr_t addr)
void space_t::init(fpage_t utcb_area, fpage_t kip_area)
{
this->utcb_area = utcb_area;
int i;
this->utcb_area = utcb_area;
this->kip_area = kip_area;
this->add_mapping( kip_area.get_base(), (paddr_t)virt_to_phys(get_kip()),
pgent_t::size_4k, false, false );
// XXX: do upon migration!
for (int i = 0; i < CONFIG_SMP_MAX_CPUS; i++)
for (i = 0; i < CONFIG_SMP_MAX_CPUS; i++)
get_asid(i)->init();
}
void SECTION(".init.memory") space_t::init_kernel_mappings()
{
int i;
this->pinned_mapping = PINNED_AREA_START;
//initialize translation table
for (i=0; i < TRANSLATION_TABLE_ENTRIES; ++i) {
transTable[i].s0addr = 0;
transTable[i].physaddr = 0;
transTable[i].size = 0;
}
}
void SECTION(".init.memory") space_t::init_cpu_mappings(cpuid_t cpu)
@ -352,33 +361,25 @@ void space_t::arch_free()
#define RELOC(s0addr, physaddr, size) \
case s0addr ... s0addr + size - 1: paddr = physaddr + reinterpret_cast<paddr_t>(addr_offset(addr, -s0addr)); break;
/* XXX: remove remapping */
paddr_t space_t::sigma0_translate(addr_t addr, pgent_t::pgsize_e size)
{
paddr_t paddr = reinterpret_cast<paddr_t>(addr);
#if defined(CONFIG_SUBPLAT_440_BGP)
switch(reinterpret_cast<word_t>(addr))
{
RELOC(0xff000000, 0x600000000ULL, 0x4000); // DMA
RELOC(0xff010000, 0x601140000ULL, 0x8000); // FIFO0
RELOC(0xff018000, 0x601150000ULL, 0x8000); // FIFO1
RELOC(0xff020000, 0x610000000ULL, 0x1000); // Tree Ch0
RELOC(0xff021000, 0x611000000ULL, 0x1000); // Tree Ch1
RELOC(0xff030000, 0x720000000ULL, 0x10000); // Tomal, Xemac, xgmii
word_t i;
paddr_t paddr = (paddr_t)addr;
for (i = 0; i < TRANSLATION_TABLE_ENTRIES; ++i) {
if ((transTable[i].size > 0) && ((word_t)addr >= transTable[i].s0addr) && ((word_t)addr <= transTable[i].s0addr + transTable[i].size - 1)) {
paddr = transTable[i].physaddr + (word_t)addr_offset(addr, -transTable[i].s0addr);
transTable[i].size = 0;
break;
}
}
#elif defined(CONFIG_SUBPLAT_440_EBONY)
switch(reinterpret_cast<word_t>(addr))
{
RELOC(0xf0000000, 0x140000000ULL, 0x10000000); // PERIPHERAL_BASE
}
#endif
return paddr;
}
word_t space_t::sigma0_attributes(pgent_t *pg, addr_t addr, pgent_t::pgsize_e size)
word_t space_t::sigma0_attributes(pgent_t *pg, paddr_t addr, pgent_t::pgsize_e size)
{
/* device memory is guarded */
if (sigma0_translate(addr, size) >= 0x100000000ULL)
//if (sigma0_translate(addr, size) >= 0x100000000ULL)
if (addr >= 0x100000000ULL)
return pgent_t::cache_inhibited;
else
return pgent_t::cache_standard;

View File

@ -57,6 +57,9 @@ EXTERN_KMEM_GROUP(kmem_space);
space_t *kernel_space = NULL;
//translation table
struct transTable_t transTable[TRANSLATION_TABLE_ENTRIES];
void space_t::allocate_tcb(addr_t addr)
{
#if !defined(CONFIG_STATIC_TCBS)
@ -301,9 +304,11 @@ void space_t::map_sigma0(addr_t addr)
add_mapping( addr, (paddr_t)addr, pgent_t::size_4k, true, false );
}
word_t space_t::space_control (word_t ctrl)
word_t space_t::space_control (word_t ctrl, fpage_t kip_area, fpage_t utcb_area, threadid_t redirector_tid)
{
word_t oldctrl = 0;
paddr_t physaddr;
int i;
#ifdef CONFIG_X_PPC_SOFTHVM
oldctrl |= this->hvm_mode ? 1 : 0;
@ -314,5 +319,19 @@ word_t space_t::space_control (word_t ctrl)
this->hvm_mode = true;
}
#endif
if (ctrl & (1 << 29)) {
for (i = 0; i < TRANSLATION_TABLE_ENTRIES; ++i) {
if (transTable[i].size > 0)
continue;
oldctrl |= 1 << 29;
physaddr = redirector_tid.get_raw();
physaddr <<= 32;
physaddr |= utcb_area.raw;
transTable[i].physaddr = physaddr;
transTable[i].s0addr = kip_area.mem.x.base << 10;
transTable[i].size = 1UL << kip_area.mem.x.size;
break;
}
}
return oldctrl;
}

View File

@ -55,6 +55,14 @@
// Even if new MDB is not used we need the mdb_t::ctrl_t
#include <mdb.h>
//translation table (actual declaration in space.cc)
#define TRANSLATION_TABLE_ENTRIES 32
extern struct transTable_t {
word_t s0addr;
paddr_t physaddr;
word_t size;
} transTable[TRANSLATION_TABLE_ENTRIES];
class utcb_t;
class tcb_t;
@ -120,7 +128,7 @@ public:
static void free_space(space_t *space);
/* space control */
word_t space_control (word_t ctrl);
word_t space_control (word_t ctrl, fpage_t kip_area, fpage_t utcb_area, threadid_t redirector_tid);
/* tlb */
void flush_tlb( space_t *curspace, addr_t start = (addr_t)0, addr_t end = (addr_t)~0U );
@ -137,7 +145,7 @@ public:
/* sigma0 translation hooks */
static paddr_t sigma0_translate(addr_t addr, pgent_t::pgsize_e size);
static word_t sigma0_attributes(pgent_t *pg, addr_t addr, pgent_t::pgsize_e size);
static word_t sigma0_attributes(pgent_t *pg, paddr_t addr, pgent_t::pgsize_e size);
public:
/* powerpc specific functions */

View File

@ -71,6 +71,9 @@ char kernel_space_segment_table[POWERPC64_STAB_SIZE] __attribute__((aligned(POWE
space_t *kernel_space = (space_t*)&kernel_space_object;
tcb_t *dummy_tcb = NULL;
//translation table
struct transTable_t transTable[TRANSLATION_TABLE_ENTRIES];
INLINE word_t pagedir_idx (addr_t addr)
{
return page_table_index (pgent_t::size_max, addr);

View File

@ -53,6 +53,13 @@
// Even if new MDB is not used we need the mdb_t::ctrl_t
#include <mdb.h>
//translation table (actual declaration in space.cc)
#define TRANSLATION_TABLE_ENTRIES 32
extern struct transTable_t {
word_t s0addr;
paddr_t physaddr;
word_t size;
} transTable[TRANSLATION_TABLE_ENTRIES];
class utcb_t;
class tcb_t;
@ -115,7 +122,11 @@ public:
bool remove_tcb(tcb_t * tcb);
/* space control */
word_t space_control (word_t ctrl) { return 0; }
word_t space_t::space_control (word_t ctrl, fpage_t kip_area, fpage_t utcb_area, threadid_t redirector_tid) { return 0; }
/* sigma0 translation hooks */
static paddr_t sigma0_translate(addr_t addr, pgent_t::pgsize_e size) { return (paddr_t)addr; }
static word_t sigma0_attributes(pgent_t *pg, addr_t addr, pgent_t::pgsize_e size) { return 0; };
/* tlb */
void flush_tlb( space_t *curspace );

View File

@ -72,7 +72,7 @@ public:
void move_tcb(tcb_t * tcb, cpuid_t src_cpu, cpuid_t dst_cpu);
/* space control */
word_t space_control (word_t ctrl);
word_t space_control (word_t ctrl, fpage_t kip_area, fpage_t utcb_area, threadid_t redirector_tid);
/* x86 specific functions */
static void init_kernel_space();
@ -100,7 +100,7 @@ public:
static void end_update();
/* sigma0 translation hooks */
static addr_t sigma0_translate(addr_t addr, pgent_t::pgsize_e size) { return addr; }
static paddr_t sigma0_translate(addr_t addr, pgent_t::pgsize_e size);
static word_t sigma0_attributes(pgent_t *pg, addr_t addr, pgent_t::pgsize_e size) { return 0; };
/* generic page table walker */

View File

@ -50,6 +50,9 @@
EXTERN_TRACEPOINT(DEBUG);
//translation table
struct transTable_t transTable[TRANSLATION_TABLE_ENTRIES];
/**********************************************************************
*
* space_t implementation
@ -202,7 +205,7 @@ word_t pgent_t::smp_reference_bits(space_t * space, pgsize_e pgsize, addr_t vadd
#if defined(CONFIG_X86_SMALL_SPACES)
word_t space_t::space_control (word_t ctrl)
word_t space_t::space_control (word_t ctrl, fpage_t kip_area, fpage_t utcb_area, threadid_t redirector_tid)
{
// Ignore parameter if 's' bit is not set.
if ((ctrl & (1 << 31)) == 0)
@ -227,8 +230,12 @@ bool is_smallspace(space_t *space)
#else /* !CONFIG_X86_SMALL_SPACES */
word_t space_t::space_control (word_t ctrl)
word_t space_t::space_control (word_t ctrl, fpage_t kip_area, fpage_t utcb_area, threadid_t redirector_tid)
{
word_t oldctrl = 0;
u64_t physaddr;
int i;
#if defined(CONFIG_X_X86_HVM)
// Check if 'v' bit is set.
if (ctrl & (1 << 30))
@ -238,10 +245,37 @@ word_t space_t::space_control (word_t ctrl)
}
#endif
return 0;
if ((ctrl & (1 << 29)) && (sizeof(paddr_t) != sizeof(u32_t))) {
for (i = 0; i < TRANSLATION_TABLE_ENTRIES; ++i) {
if (transTable[i].size > 0)
continue;
oldctrl |= 1 << 29;
//printf("UTCB: 0x%x, redirect: 0x%x, KIP: 0x%x\n", utcb_area.raw, redirector_tid.get_raw(), kip_area.raw);
physaddr = redirector_tid.get_raw();
physaddr <<= 32;
physaddr |= utcb_area.raw;
transTable[i].physaddr = (paddr_t)physaddr;
transTable[i].s0addr = kip_area.mem.x.base << 10;
transTable[i].size = 1UL << kip_area.mem.x.size;
break;
}
}
return oldctrl;
}
paddr_t space_t::sigma0_translate(addr_t addr, pgent_t::pgsize_e size)
{
word_t i;
paddr_t paddr = (paddr_t)addr;
for (i = 0; i < TRANSLATION_TABLE_ENTRIES; ++i) {
if ((transTable[i].size > 0) && ((word_t)addr >= transTable[i].s0addr) && ((word_t)addr <= transTable[i].s0addr + transTable[i].size - 1)) {
paddr = transTable[i].physaddr + (word_t)addr_offset(addr, -transTable[i].s0addr);
transTable[i].size = 0;
break;
}
}
return paddr;
}
#endif

View File

@ -58,6 +58,14 @@
// Even if new MDB is not used we need the mdb_t::ctrl_t
#include <mdb.h>
//translation table (actual declaration in space.cc)
#define TRANSLATION_TABLE_ENTRIES 32
extern struct transTable_t {
word_t s0addr;
paddr_t physaddr;
word_t size;
} transTable[TRANSLATION_TABLE_ENTRIES];
#define PGSIZE_KTCB (pgent_t::size_4k)
#define PGSIZE_UTCB (pgent_t::size_4k)
#define PGSIZE_KERNEL ((KERNEL_PAGE_SIZE == X86_SUPERPAGE_SIZE) ? pgent_t::size_4m : pgent_t::size_4k)

View File

@ -51,7 +51,8 @@
#include INC_GLUE_SA(x32comp/kernelinterface.h)
#endif /* defined(CONFIG_X86_COMPATIBILITY_MODE) */
//translation table
struct transTable_t transTable[TRANSLATION_TABLE_ENTRIES];
word_t space_t::readmem_phys(addr_t paddr)
@ -165,10 +166,14 @@ word_t space_t::space_control(word_t ctrl)
#else /* !defined(CONFIG_X86_COMPATIBILITY_MODE) */
word_t space_t::space_control(word_t ctrl)
word_t space_t::space_control (word_t ctrl, fpage_t kip_area, fpage_t utcb_area, threadid_t redirector_tid)
{
return 0;
}
paddr_t space_t::sigma0_translate(addr_t addr, pgent_t::pgsize_e size) {
return (paddr_t)addr;
}
#endif /* defined(CONFIG_X86_COMPATIBILITY_MODE) */

View File

@ -56,6 +56,13 @@ class utcb_t;
#define PGSIZE_KERNEL ((KERNEL_PAGE_SIZE == X86_SUPERPAGE_SIZE) ? pgent_t::size_2m : pgent_t::size_4k)
#define PGSIZE_SIGMA pgent_t::size_2m
//translation table (actual declaration in space.cc)
#define TRANSLATION_TABLE_ENTRIES 32
extern struct transTable_t {
word_t s0addr;
paddr_t physaddr;
word_t size;
} transTable[TRANSLATION_TABLE_ENTRIES];
/**
* The address space representation

View File

@ -33,6 +33,8 @@
#define __GLUE_V4_X86__X64__TCB_H__
#include INC_ARCH_SA(tss.h) /* for x86_x64_tss_t */
#include INC_API(fpage.h)
#include INC_API(thread.h)
#if defined(CONFIG_X86_COMPATIBILITY_MODE)
#include INC_GLUE_SA(x32comp/tcb.h)
@ -333,7 +335,7 @@ INLINE addr_t tcb_t::copy_area_real_address (addr_t addr)
/**********************************************************************
*
* global tcb functions
*
*L4_Nilpage
**********************************************************************/
@ -361,7 +363,7 @@ INLINE tcb_t * get_current_tcb()
*/
INLINE void tcb_t::arch_init_root_server (space_t * space, word_t ip, word_t sp)
{
space->space_control(sp);
space->space_control(sp, fpage_t::nilpage(), fpage_t::nilpage(), threadid_t::nilthread());
}
#endif /* !__GLUE_V4_X86__X64__TCB_H__ */

View File

@ -53,6 +53,7 @@ typedef signed char L4_SignedWord8_t;
typedef signed long L4_SignedWord_t;
typedef unsigned long L4_Size_t;
typedef L4_Word64_t L4_Paddr_t;
#else /* !ELF_LOADER_32BIT */

View File

@ -52,5 +52,6 @@ typedef signed char L4_SignedWord8_t;
typedef signed long L4_SignedWord_t;
typedef unsigned int L4_Size_t;
typedef L4_Word64_t L4_Paddr_t;
#endif /* !__L4__X86__TYPES_H__ */

View File

@ -51,5 +51,6 @@ typedef signed char L4_SignedWord8_t;
typedef signed long L4_SignedWord_t;
typedef unsigned int L4_Size_t;
typedef L4_Word64_t L4_Paddr_t;
#endif /* __L4__POWERPC__TYPES_H__ */

View File

@ -51,5 +51,6 @@ typedef signed char L4_SignedWord8_t;
typedef signed long L4_SignedWord_t;
typedef long unsigned int L4_Size_t;
typedef L4_Word64_t L4_Paddr_t;
#endif /* __L4__POWERPC64__TYPES_H__ */

View File

@ -39,7 +39,8 @@
L4_INLINE L4_Fpage_t L4_Sigma0_GetPage_RcvWindow (L4_ThreadId_t s0,
L4_Fpage_t f,
L4_Fpage_t RcvWindow)
L4_Fpage_t RcvWindow,
L4_Word_t high)
{
L4_MsgTag_t tag;
L4_Msg_t msg;
@ -54,6 +55,9 @@ L4_INLINE L4_Fpage_t L4_Sigma0_GetPage_RcvWindow (L4_ThreadId_t s0,
L4_MsgClear (&msg);
L4_MsgAppendWord (&msg, f.raw);
L4_MsgAppendWord (&msg, 0);
if (f.X.extended == 1) {
L4_MsgAppendWord (&msg, high);
}
L4_Set_MsgLabel (&msg, (L4_Word_t) -6UL << 4);
L4_MsgLoad (&msg);
L4_Accept (L4_MapGrantItems (RcvWindow));
@ -71,20 +75,37 @@ L4_INLINE L4_Fpage_t L4_Sigma0_GetPage (L4_ThreadId_t s0,
L4_Fpage_t f,
L4_Fpage_t RcvWindow)
{
return L4_Sigma0_GetPage_RcvWindow (s0, f, RcvWindow);
return L4_Sigma0_GetPage_RcvWindow (s0, f, RcvWindow, 0);
}
#endif
L4_INLINE L4_Fpage_t L4_Sigma0_GetPage (L4_ThreadId_t s0, L4_Fpage_t f)
{
return L4_Sigma0_GetPage_RcvWindow (s0, f, L4_CompleteAddressSpace);
return L4_Sigma0_GetPage_RcvWindow (s0, f, L4_CompleteAddressSpace, 0);
}
L4_INLINE L4_Fpage_t L4_Sigma0_GetPage (L4_ThreadId_t s0,
L4_Fpage_t f,
L4_Word_t high)
{
f.X.extended = 1;
return L4_Sigma0_GetPage_RcvWindow (s0, f, L4_CompleteAddressSpace, high);
}
L4_INLINE L4_Fpage_t L4_Sigma0_GetPage (L4_ThreadId_t s0,
L4_Fpage_t f,
L4_Word_t high,
L4_Fpage_t RcvWindow)
{
f.X.extended = 1;
return L4_Sigma0_GetPage_RcvWindow (s0, f, RcvWindow, high);
}
L4_INLINE L4_Fpage_t L4_Sigma0_GetAny (L4_ThreadId_t s0,
L4_Word_t s,
L4_Fpage_t RcvWindow)
{
return L4_Sigma0_GetPage_RcvWindow (s0, L4_FpageLog2 (~0UL, s), RcvWindow);
return L4_Sigma0_GetPage_RcvWindow (s0, L4_FpageLog2 (~0UL, s), RcvWindow, 0);
}
@ -128,7 +149,7 @@ L4_INLINE void *L4_Sigma0_GetSpecial(L4_Word_t type, void* address, L4_Word_t pa
L4_Fpage_t rcvfpage = L4_Fpage( rcvstart, pagesize );
fpage.X.rwx = L4_ReadWriteOnly;
fpage = L4_Sigma0_GetPage_RcvWindow( sigma0, fpage, rcvfpage );
fpage = L4_Sigma0_GetPage_RcvWindow( sigma0, fpage, rcvfpage, 0 );
if( L4_IsNilFpage(fpage) )
return address;

View File

@ -149,7 +149,7 @@ typedef union {
struct {
L4_BITFIELD4(L4_Word_t,
rwx : 3,
reserved : 1,
extended : 1,
s : 6,
b : 22 __PLUS32);
} X;

View File

@ -115,9 +115,15 @@ static void io_init( void )
// Install it as the 2nd page in our address space.
// Hopefully it is free!
L4_Fpage_t target = L4_Fpage( 4096, 4096 );
#if 0
L4_Fpage_t fpage = L4_Fpage( reg[1], 4096 );
fpage.X.rwx = L4_ReadWriteOnly;
fpage = L4_Sigma0_GetPage( sigma0, fpage, target );
#else
L4_Fpage_t fpage = L4_Fpage(0x40000000,4096);
fpage.X.rwx = L4_ReadWriteOnly;
fpage = L4_Sigma0_GetPage( sigma0, fpage, 0x1, target );
#endif
if( L4_IsNilFpage(fpage) )
return;
@ -189,10 +195,15 @@ static void io_init( void )
// Hopefully it is free!
L4_Fpage_t target = L4_Fpage( (L4_Word_t) comport, 4096 );
#if 0
L4_Fpage_t fpage = L4_Fpage( comport_phys, 4096 );
fpage.X.rwx = L4_ReadWriteOnly;
fpage = L4_Sigma0_GetPage( sigma0, fpage, target );
#else
L4_Fpage_t fpage = L4_Fpage(0x40000200,4096);
fpage.X.rwx = L4_ReadWriteOnly;
fpage = L4_Sigma0_GetPage( sigma0, fpage, 0x1, target );
#endif
if( L4_IsNilFpage(fpage) )
return;

View File

@ -50,7 +50,7 @@ region_list_t region_list;
**
*/
region_t::region_t (L4_Word_t l, L4_Word_t h, L4_ThreadId_t o)
region_t::region_t (L4_Paddr_t l, L4_Paddr_t h, L4_ThreadId_t o)
{
low = l;
high = h;
@ -142,15 +142,19 @@ L4_Fpage_t region_t::allocate (L4_Word_t log2size, L4_ThreadId_t tid,
L4_Word_t size = 1UL << log2size;
L4_Fpage_t ret;
L4_Fpage_t kip_area, utcb_area;
L4_Word_t control, shortaddr;
L4_ThreadId_t redirector;
// Low and high address of region within mwmregion when they are
// aligned according to log2size. Note that these values might
// overflow and must as such be handled with care.
L4_Word_t low_a = (low + size - 1) & ~(size-1);
L4_Word_t high_a = ((high + 1) & ~(size-1)) - 1;
L4_Paddr_t low_a = (low + size - 1) & ~(size-1);
L4_Paddr_t high_a = ((high + 1) & ~(size-1)) - 1;
if (low_a > high_a // Low rounded up to above high
|| low > low_a // Low wrapped around
|| high < size-1 // High wrapper around
|| high < size-1 // High wrapped around
|| (high_a - low_a) < size-1 // Not enough space in region
|| (owner != tid && owner != L4_anythread))
{
@ -160,7 +164,20 @@ L4_Fpage_t region_t::allocate (L4_Word_t log2size, L4_ThreadId_t tid,
else if (low_a == low)
{
// Allocate from start of region
ret = make_fpage (low, log2size) + L4_FullyAccessible;
if (low != (L4_Word_t)low) { //extended mapping
shortaddr = (L4_Word_t)low;
kip_area.X.s = log2size;
kip_area.X.b = shortaddr >> 10;
redirector.raw = low >> 32;
utcb_area.raw = shortaddr;
L4_SpaceControl(sigma0_id,1 << 29, kip_area, utcb_area, redirector,
&control);
}
ret = make_fpage ((L4_Word_t)low, log2size) + L4_FullyAccessible;
if (low + size == high + 1)
remove ();
else
@ -169,13 +186,38 @@ L4_Fpage_t region_t::allocate (L4_Word_t log2size, L4_ThreadId_t tid,
else if (high_a == high)
{
// Allocate from end of region
ret = make_fpage (high_a - size + 1, log2size) + L4_FullyAccessible;
if (high_a != (L4_Word_t)high_a) { //extended mapping
shortaddr = (L4_Word_t)(high_a - size + 1);
kip_area.X.s = log2size;
kip_area.X.b = shortaddr >> 10;
redirector.raw = low >> 32;
utcb_area.raw = shortaddr;
L4_SpaceControl(sigma0_id,1 << 29, kip_area, utcb_area, redirector,
&control);
}
ret = make_fpage ((L4_Word_t)(high_a) - size + 1, log2size) + L4_FullyAccessible;
high -= size;
}
else
{
// Allocate from middle of region
ret = make_fpage (low_a, log2size) + L4_FullyAccessible;
if (low_a != (L4_Word_t)low_a) { //extended mapping
shortaddr = (L4_Word_t)low_a;
kip_area.X.s = log2size;
kip_area.X.b = shortaddr >> 10;
redirector.raw = low >> 32;
utcb_area.raw = shortaddr;
L4_SpaceControl(sigma0_id,1 << 29, kip_area, utcb_area, redirector,
&control);
}
ret = make_fpage ((L4_Word_t)low_a, log2size) + L4_FullyAccessible;
region_t * r = new region_t (low_a + size, high, owner);
r->next = next;
r->prev = this;
@ -199,7 +241,7 @@ L4_Fpage_t region_t::allocate (L4_Word_t log2size, L4_ThreadId_t tid,
*
* @return fpage for allocated region if successful, nilpage otherwise
*/
L4_Fpage_t region_t::allocate (L4_Word_t addr, L4_Word_t log2size,
L4_Fpage_t region_t::allocate (L4_Paddr_t addr, L4_Word_t log2size,
L4_ThreadId_t tid,
L4_Fpage_t (*make_fpage) (L4_Word_t, int))
{
@ -209,8 +251,8 @@ L4_Fpage_t region_t::allocate (L4_Word_t addr, L4_Word_t log2size,
// Low and high address of region within mwmregion when they are
// aligned according to log2size. Note that these values might
// overflow and must as such be handled with care.
L4_Word_t low_a = (low + size - 1) & ~(size-1);
L4_Word_t high_a = ((high + 1) & ~(size-1)) - 1;
L4_Paddr_t low_a = (low + size - 1) & ~(size-1);
L4_Paddr_t high_a = ((high + 1) & ~(size-1)) - 1;
if (addr < low_a // Address range below low
|| (addr + size - 1) > high_a // Address range above high
@ -225,7 +267,7 @@ L4_Fpage_t region_t::allocate (L4_Word_t addr, L4_Word_t log2size,
else if (low_a == low && addr == low)
{
// Allocate from start of region
ret = make_fpage (low, log2size) + L4_FullyAccessible;
ret = make_fpage ((L4_Word_t)low, log2size) + L4_FullyAccessible;
if (low + size == high + 1)
remove ();
else
@ -234,13 +276,13 @@ L4_Fpage_t region_t::allocate (L4_Word_t addr, L4_Word_t log2size,
else if (high_a == high && (addr + size - 1) == high)
{
// Allocate from end of region
ret = make_fpage (high_a - size + 1, log2size) + L4_FullyAccessible;
ret = make_fpage ((L4_Word_t)(high_a - size + 1), log2size) + L4_FullyAccessible;
high -= size;
}
else
{
// Allocate from middle of region
ret = make_fpage (addr, log2size) + L4_FullyAccessible;
ret = make_fpage ((L4_Word_t)addr, log2size) + L4_FullyAccessible;
region_t * r = new region_t (addr + size, high, owner);
r->next = next;
r->prev = this;
@ -261,7 +303,7 @@ L4_Fpage_t region_t::allocate (L4_Word_t addr, L4_Word_t log2size,
*
* @return true if allocation is possible, false otherwise
*/
bool region_t::can_allocate (L4_Word_t addr, L4_Word_t log2size,
bool region_t::can_allocate (L4_Paddr_t addr, L4_Word_t log2size,
L4_ThreadId_t tid)
{
L4_Word_t size = 1UL << log2size;
@ -269,8 +311,8 @@ bool region_t::can_allocate (L4_Word_t addr, L4_Word_t log2size,
// Low and high address of region within mwmregion when they are
// aligned according to log2size. Note that these values might
// overflow and must as such be handled with care.
L4_Word_t low_a = (low + size - 1) & ~(size-1);
L4_Word_t high_a = ((high + 1) & ~(size-1)) - 1;
L4_Paddr_t low_a = (low + size - 1) & ~(size-1);
L4_Paddr_t high_a = ((high + 1) & ~(size-1)) - 1;
if (addr < low_a // Address range below low
|| (addr + size - 1) > high_a // Address range above high
@ -298,7 +340,7 @@ bool region_t::can_allocate (L4_Word_t addr, L4_Word_t log2size,
* @param addr location of memory to add
* @param size amount of memory to add
*/
void region_list_t::add (L4_Word_t addr, L4_Word_t size)
void region_list_t::add (L4_Paddr_t addr, L4_Word_t size)
{
if (addr == 0)
{
@ -463,7 +505,7 @@ void region_pool_t::remove (region_t * r)
* @param high upper limit of memory region
* @param owner owner of memory region
*/
void region_pool_t::insert (L4_Word_t low, L4_Word_t high,
void region_pool_t::insert (L4_Paddr_t low, L4_Paddr_t high,
L4_ThreadId_t owner)
{
insert (new region_t (low, high, owner));
@ -476,7 +518,7 @@ void region_pool_t::insert (L4_Word_t low, L4_Word_t high,
* @param low lower limit of memory region to remove
* @param high upper limit of memory region to remove
*/
void region_pool_t::remove (L4_Word_t low, L4_Word_t high)
void region_pool_t::remove (L4_Paddr_t low, L4_Paddr_t high)
{
region_t * n = first.next;

View File

@ -40,15 +40,15 @@ class region_t
{
public:
L4_Word_t low;
L4_Word_t high;
L4_Paddr_t low;
L4_Paddr_t high;
L4_ThreadId_t owner;
region_t *prev;
region_t *next;
region_t (void) {}
region_t (L4_Word_t low, L4_Word_t high, L4_ThreadId_t owner);
region_t (L4_Paddr_t low, L4_Paddr_t high, L4_ThreadId_t owner);
void * operator new (L4_Size_t size);
@ -57,9 +57,9 @@ public:
bool is_adjacent (const region_t & r);
bool concatenate (region_t * reg);
bool can_allocate (L4_Word_t addr, L4_Word_t log2size,
bool can_allocate (L4_Paddr_t addr, L4_Word_t log2size,
L4_ThreadId_t tid);
L4_Fpage_t allocate (L4_Word_t addr, L4_Word_t log2size, L4_ThreadId_t tid,
L4_Fpage_t allocate (L4_Paddr_t addr, L4_Word_t log2size, L4_ThreadId_t tid,
L4_Fpage_t (*make_fpage) (L4_Word_t, int));
L4_Fpage_t allocate (L4_Word_t log2size, L4_ThreadId_t tid,
L4_Fpage_t (*make_fpage) (L4_Word_t, int));
@ -95,7 +95,7 @@ class region_list_t
public:
void add (L4_Word_t addr, L4_Word_t size);
void add (L4_Paddr_t addr, L4_Word_t size);
L4_Word_t contents (void);
region_t * alloc (void);
void free (region_t * r);
@ -117,8 +117,8 @@ public:
void dump (void);
void insert (region_t * r);
void remove (region_t * r);
void insert (L4_Word_t low, L4_Word_t high, L4_ThreadId_t owner);
void remove (L4_Word_t low, L4_Word_t high);
void insert (L4_Paddr_t low, L4_Paddr_t high, L4_ThreadId_t owner);
void remove (L4_Paddr_t low, L4_Paddr_t high);
void reset (void);
region_t * next (void);
};

View File

@ -128,7 +128,6 @@ extern "C" void sigma0_main (void)
L4_ThreadId_t tid;
L4_Accept (L4_UntypedWordsAcceptor);
L4_Reset_WordSizeMask();
tag = L4_Wait (&tid);
for (;;)
@ -144,7 +143,7 @@ extern "C" void sigma0_main (void)
while (L4_IpcFailed (tag))
tag = L4_Wait (&tid);
if (L4_UntypedWords (tag) != 2 || L4_TypedWords (tag) != 0)
if ((L4_UntypedWords (tag) != 2 && L4_UntypedWords (tag) != 3) || L4_TypedWords (tag) != 0)
{
dprintf (0, "s0: malformed request from %p (tag=%p)\n",
(void *) tid.raw, (void *) tag.raw);
@ -209,7 +208,13 @@ extern "C" void sigma0_main (void)
break;
}
#endif
L4_Word_t addr = L4_Address (fpage);
L4_Paddr_t addr;
if (fpage.X.extended == 1) {
addr = L4_Get(&msg,2);
addr <<= 32;
addr |= L4_Address (fpage);
} else
addr = L4_Address (fpage);
L4_Word_t attributes = L4_Get (&msg, 1);
if (is_kernel_thread (tid))

View File

@ -93,7 +93,7 @@ L4_INLINE bool is_kernel_thread (L4_ThreadId_t t)
/* From sigma0_mem.cc */
void init_mempool (void);
void dump_mempools (void);
bool allocate_page (L4_ThreadId_t tid, L4_Word_t addr, L4_Word_t log2size,
bool allocate_page (L4_ThreadId_t tid, L4_Paddr_t addr, L4_Word_t log2size,
L4_MapItem_t & map, bool only_conventional = false);
bool allocate_page (L4_ThreadId_t tid, L4_Word_t log2size, L4_MapItem_t & map);

View File

@ -292,7 +292,7 @@ void dump_mempools (void)
*
* @return true upon success, false otherwise
*/
bool allocate_page (L4_ThreadId_t tid, L4_Word_t addr, L4_Word_t log2size,
bool allocate_page (L4_ThreadId_t tid, L4_Paddr_t addr, L4_Word_t log2size,
L4_MapItem_t & map, bool only_conventional)
{
region_t * r;
@ -307,8 +307,24 @@ bool allocate_page (L4_ThreadId_t tid, L4_Word_t addr, L4_Word_t log2size,
return false;
// Make sure that addr is properly aligned.
addr &= ~((1UL << log2size) - 1);
L4_Word_t addr_high = addr + (1UL << log2size) - 1;
addr &= ~(((L4_Paddr_t)1UL << log2size) - 1);
L4_Paddr_t addr_high = addr + (1UL << log2size) - 1;
L4_Fpage_t kip_area, utcb_area;
L4_Word_t control;
L4_ThreadId_t redirector;
L4_Word_t shortaddr = (L4_Word_t)addr;
if (addr != (L4_Word_t)addr) { //extended mapping
kip_area.X.s = log2size;
kip_area.X.b = shortaddr >> 10;
redirector.raw = addr >> 32;
utcb_area.raw = shortaddr;
L4_SpaceControl(sigma0_id,1 << 29, kip_area, utcb_area, redirector,
&control);
}
region_pool_t * pools[] = { &conv_memory_pool, &memory_pool,
(region_pool_t *) NULL };
@ -364,9 +380,9 @@ bool allocate_page (L4_ThreadId_t tid, L4_Word_t addr, L4_Word_t log2size,
{
// Use smallest page size as stepping
for (L4_Word_t a = addr; a < addr_high; a += (1UL << min_pgsize))
for (L4_Paddr_t a = addr; a < addr_high; a += (1UL << min_pgsize))
{
L4_Word_t a_end = a + (1UL << min_pgsize);
L4_Paddr_t a_end = a + (1UL << min_pgsize);
bool failed = true;
// Try the different pools
@ -398,8 +414,8 @@ bool allocate_page (L4_ThreadId_t tid, L4_Word_t addr, L4_Word_t log2size,
}
}
map = L4_MapItem (L4_FpageLog2 (addr, log2size) + L4_FullyAccessible,
addr);
map = L4_MapItem (L4_FpageLog2 ((L4_Word_t)addr, log2size) + L4_FullyAccessible,
(L4_Word_t)addr);
return true;
}