L4Linux stability improvements

- search for alternative virtual address regions upwards, starting from
  the given start address, in the 'l4re_rm_attach()' and
  'Region_manager::reserve_range()' functions

- don't treat memory locations above 0x80000000 in l4linux's virtual
  address space as device memory

- align the start address of the vmalloc area according to the assumption
  in 'devicemaps_init()'

Fixes #414.
This commit is contained in:
Christian Prochaska 2013-03-06 15:34:08 +01:00 committed by Norman Feske
parent a59b2e3f16
commit b38fee2867
4 changed files with 294 additions and 196 deletions

View File

@ -1,64 +1,3 @@
Index: arch/l4/boot/Makefile
===================================================================
--- arch/l4/boot/Makefile (revision 25)
+++ arch/l4/boot/Makefile (working copy)
@@ -10,7 +10,7 @@
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
-lImage: $(obj)/Image vmlinuz$(VMLINUZ_SUFFIX) l4linux$(VMLINUZ_SUFFIX)
+lImage: $(obj)/Image
vmlinuz$(VMLINUZ_SUFFIX): ldrImage FORCE
$(call if_changed,gzip)
@@ -21,8 +21,8 @@
objects-y := ldr.o res.o image.o
-include $(L4OBJ)/l4defs.mk.inc
-
+#include $(L4OBJ)/l4defs.mk.inc
+KBUILD_CFLAGS_i386 = -m32
KBUILD_CFLAGS := $(filter-out -mregparm=3,$(KBUILD_CFLAGS)) \
$(L4INC) -I$(L4OBJ)/include/uclibc \
-Wall -fno-strict-aliasing -O2 -pipe \
Index: arch/l4/lib/pte.c
===================================================================
--- arch/l4/lib/pte.c (revision 25)
+++ arch/l4/lib/pte.c (working copy)
@@ -18,7 +18,10 @@
#include <l4/sys/task.h>
#include <l4/sys/kdebug.h>
#include <l4/re/consts.h>
+#include <l4/log/log.h>
+extern void l4lx_memory_map_physical_page(unsigned long address);
+
static void l4x_flush_page(struct mm_struct *mm,
unsigned long address,
unsigned long vaddr,
@@ -77,7 +80,7 @@
if (mm && !l4_is_invalid_cap(mm->context.task)) {
L4XV_V(f);
if (!mm->context.task)
- l4x_printf("%s: Ups, task == 0\n", __func__);
+ LOG_printf("%s: Ups, task == 0\n", __func__);
/* Direct flush in the child, use virtual address in the
* child address space */
L4XV_L(f);
@@ -93,10 +96,11 @@
tag = l4_task_unmap(L4RE_THIS_TASK_CAP,
l4_fpage(address & PAGE_MASK, size, flush_rights),
L4_FP_OTHER_SPACES);
+ l4lx_memory_map_physical_page(address);
L4XV_U(f);
}
if (l4_error(tag))
- l4x_printf("l4_task_unmap error %ld\n", l4_error(tag));
+ LOG_printf("l4_task_unmap error %ld\n", l4_error(tag));
}
#ifdef ARCH_arm
Index: arch/l4/Makefile Index: arch/l4/Makefile
=================================================================== ===================================================================
--- arch/l4/Makefile (revision 25) --- arch/l4/Makefile (revision 25)
@ -190,28 +129,6 @@ Index: arch/l4/Kconfig
endmenu # stub drivers endmenu # stub drivers
menu "Debugging options" menu "Debugging options"
Index: arch/l4/kernel/dispatch.c
===================================================================
--- arch/l4/kernel/dispatch.c (revision 25)
+++ arch/l4/kernel/dispatch.c (working copy)
@@ -271,7 +271,7 @@
return 0;
if (l4_msgtag_is_page_fault(tag)) {
- l4x_printf("HYBRID PF!!\n");
+ LOG_printf("HYBRID PF!!\n");
/* No exception IPC, it's a page fault, but shouldn't happen */
goto out_fail;
}
@@ -695,7 +695,7 @@
enter_kdebug("non hybrid in idle?!");
} else {
if (unlikely(l4x_handle_async_event(label, utcb, tag)))
- l4x_printf("Async return with error\n");
+ LOG_printf("Async return with error\n");
}
}
}
Index: arch/l4/kernel/arch-arm/traps.c Index: arch/l4/kernel/arch-arm/traps.c
=================================================================== ===================================================================
--- arch/l4/kernel/arch-arm/traps.c (revision 25) --- arch/l4/kernel/arch-arm/traps.c (revision 25)
@ -385,19 +302,53 @@ Index: arch/l4/kernel/arch-arm/vmlinux.lds.S
_end = .; _end = .;
STABS_DEBUG STABS_DEBUG
Index: arch/l4/kernel/arch-x86/x86_init.c Index: arch/l4/kernel/arch-x86/rtc.c
=================================================================== ===================================================================
--- arch/l4/kernel/arch-x86/x86_init.c (revision 25) --- arch/l4/kernel/arch-x86/rtc.c (revision 25)
+++ arch/l4/kernel/arch-x86/x86_init.c (working copy) +++ arch/l4/kernel/arch-x86/rtc.c (working copy)
@@ -42,7 +42,7 @@ @@ -163,6 +163,7 @@
struct x86_init_ops x86_init __initdata = { /* Routines for accessing the CMOS RAM/RTC. */
unsigned char rtc_cmos_read(unsigned char addr)
{
+#ifdef NOT_GENODE
#ifndef CONFIG_L4_EXTERNAL_RTC
unsigned char val;
@@ -175,17 +176,22 @@
#else
return 0;
#endif
+#else /* NOT_GENODE */
+ return 0;
+#endif /* NOT_GENODE */
}
EXPORT_SYMBOL(rtc_cmos_read);
void rtc_cmos_write(unsigned char val, unsigned char addr)
{
+#ifdef NOT_GENODE
#ifndef CONFIG_L4_EXTERNAL_RTC
lock_cmos_prefix(addr);
outb(addr, RTC_PORT(0));
outb(val, RTC_PORT(1));
lock_cmos_suffix(addr);
#endif
+#endif /* NOT_GENODE */
}
EXPORT_SYMBOL(rtc_cmos_write);
Index: arch/l4/kernel/arch-x86/dispatch.c
===================================================================
--- arch/l4/kernel/arch-x86/dispatch.c (revision 25)
+++ arch/l4/kernel/arch-x86/dispatch.c (working copy)
@@ -749,6 +749,7 @@
TBUF_LOG_EXCP(fiasco_tbuf_log_3val("except ", TBUF_TID(t->user_thread_id), t->trap_nr, t->error_code));
+ fiasco_tbuf_log_3val("except ", t->trap_nr, regs->ip, 0);
if (l4x_deliver_signal(r_trapno(t, v), r_err(t, v)))
return 0; /* handled signal, reply */
.resources = {
- .probe_roms = probe_roms,
+ .probe_roms = x86_init_noop,
.reserve_resources = reserve_standard_io_resources,
.memory_setup = l4x_memory_setup,
},
Index: arch/l4/kernel/arch-x86/vmlinux.lds.S Index: arch/l4/kernel/arch-x86/vmlinux.lds.S
=================================================================== ===================================================================
--- arch/l4/kernel/arch-x86/vmlinux.lds.S (revision 25) --- arch/l4/kernel/arch-x86/vmlinux.lds.S (revision 25)
@ -600,18 +551,19 @@ Index: arch/l4/kernel/arch-x86/vmlinux.lds.S
_end = .; _end = .;
STABS_DEBUG STABS_DEBUG
Index: arch/l4/kernel/arch-x86/dispatch.c Index: arch/l4/kernel/arch-x86/x86_init.c
=================================================================== ===================================================================
--- arch/l4/kernel/arch-x86/dispatch.c (revision 25) --- arch/l4/kernel/arch-x86/x86_init.c (revision 25)
+++ arch/l4/kernel/arch-x86/dispatch.c (working copy) +++ arch/l4/kernel/arch-x86/x86_init.c (working copy)
@@ -749,6 +749,7 @@ @@ -42,7 +42,7 @@
struct x86_init_ops x86_init __initdata = {
TBUF_LOG_EXCP(fiasco_tbuf_log_3val("except ", TBUF_TID(t->user_thread_id), t->trap_nr, t->error_code));
+ fiasco_tbuf_log_3val("except ", t->trap_nr, regs->ip, 0);
if (l4x_deliver_signal(r_trapno(t, v), r_err(t, v)))
return 0; /* handled signal, reply */
.resources = {
- .probe_roms = probe_roms,
+ .probe_roms = x86_init_noop,
.reserve_resources = reserve_standard_io_resources,
.memory_setup = l4x_memory_setup,
},
Index: arch/l4/kernel/timer.c Index: arch/l4/kernel/timer.c
=================================================================== ===================================================================
--- arch/l4/kernel/timer.c (revision 25) --- arch/l4/kernel/timer.c (revision 25)
@ -808,13 +760,14 @@ Index: arch/l4/kernel/main.c
return 1; return 1;
} }
@@ -1283,15 +1307,17 @@ @@ -1283,16 +1307,19 @@
0, "Main memory"); 0, "Main memory");
/* Reserve some part of the virtual address space for vmalloc */ /* Reserve some part of the virtual address space for vmalloc */
- l4x_vmalloc_memory_start = (unsigned long)l4x_main_memory_start; - l4x_vmalloc_memory_start = (unsigned long)l4x_main_memory_start;
- if (l4re_rm_reserve_area(&l4x_vmalloc_memory_start, - if (l4re_rm_reserve_area(&l4x_vmalloc_memory_start,
+ l4x_vmalloc_memory_start = (unsigned long)l4x_main_memory_start + l4x_mainmem_size; + l4x_vmalloc_memory_start = ((((unsigned long)l4x_main_memory_start + l4x_mainmem_size) +
+ VMALLOC_OFFSET) & ~(VMALLOC_OFFSET - 1));
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
- __VMALLOC_RESERVE, - __VMALLOC_RESERVE,
+ l4x_vmalloc_memory_size = __VMALLOC_RESERVE; + l4x_vmalloc_memory_size = __VMALLOC_RESERVE;
@ -825,13 +778,15 @@ Index: arch/l4/kernel/main.c
- VMALLOC_SIZE << 20, - VMALLOC_SIZE << 20,
+ l4x_vmalloc_memory_size = VMALLOC_SIZE << 20; + l4x_vmalloc_memory_size = VMALLOC_SIZE << 20;
#endif #endif
- L4RE_RM_SEARCH_ADDR, PGDIR_SHIFT)) {
+ +
+ if (l4re_rm_reserve_area(&l4x_vmalloc_memory_start, + if (l4re_rm_reserve_area(&l4x_vmalloc_memory_start,
+ l4x_vmalloc_memory_size, + l4x_vmalloc_memory_size,
L4RE_RM_SEARCH_ADDR, PGDIR_SHIFT)) { + L4RE_RM_SEARCH_ADDR, ilog2(VMALLOC_OFFSET))) {
LOG_printf("%s: Error reserving vmalloc memory area!\n", __func__); LOG_printf("%s: Error reserving vmalloc memory area!\n", __func__);
l4x_exit_l4linux(); l4x_exit_l4linux();
@@ -1305,7 +1331,7 @@ }
@@ -1305,7 +1332,7 @@
#ifdef ARCH_x86 #ifdef ARCH_x86
// fixmap area // fixmap area
@ -840,7 +795,7 @@ Index: arch/l4/kernel/main.c
if (l4re_rm_reserve_area(&l4x_fixmap_space_start, if (l4re_rm_reserve_area(&l4x_fixmap_space_start,
__end_of_fixed_addresses * PAGE_SIZE, __end_of_fixed_addresses * PAGE_SIZE,
L4RE_RM_SEARCH_ADDR, PAGE_SHIFT) < 0) { L4RE_RM_SEARCH_ADDR, PAGE_SHIFT) < 0) {
@@ -1416,6 +1442,10 @@ @@ -1416,6 +1443,10 @@
static void l4x_create_ugate(l4_cap_idx_t forthread, unsigned cpu) static void l4x_create_ugate(l4_cap_idx_t forthread, unsigned cpu)
{ {
@ -851,7 +806,7 @@ Index: arch/l4/kernel/main.c
l4_msgtag_t r; l4_msgtag_t r;
l4x_user_gate[cpu] = l4x_cap_alloc_noctx(); l4x_user_gate[cpu] = l4x_cap_alloc_noctx();
@@ -1436,6 +1466,7 @@ @@ -1436,6 +1467,7 @@
l4_debugger_set_object_name(l4x_user_gate[cpu], n); l4_debugger_set_object_name(l4x_user_gate[cpu], n);
#endif #endif
} }
@ -859,7 +814,7 @@ Index: arch/l4/kernel/main.c
} }
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
@@ -1641,11 +1672,15 @@ @@ -1641,11 +1673,15 @@
l4x_exit_l4linux(); l4x_exit_l4linux();
} }
@ -875,7 +830,7 @@ Index: arch/l4/kernel/main.c
#ifdef CONFIG_L4_DEBUG_REGISTER_NAMES #ifdef CONFIG_L4_DEBUG_REGISTER_NAMES
l4_debugger_set_object_name(c, s); l4_debugger_set_object_name(c, s);
@@ -1906,8 +1941,12 @@ @@ -1906,8 +1942,12 @@
static int l4x_cpu_virt_phys_map_init(const char *boot_command_line) static int l4x_cpu_virt_phys_map_init(const char *boot_command_line)
{ {
@ -888,7 +843,7 @@ Index: arch/l4/kernel/main.c
unsigned i; unsigned i;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
@@ -1923,9 +1962,10 @@ @@ -1923,9 +1963,10 @@
} }
} }
@ -900,7 +855,7 @@ Index: arch/l4/kernel/main.c
if ((p = strstr(boot_command_line, "l4x_cpus_map="))) { if ((p = strstr(boot_command_line, "l4x_cpus_map="))) {
// l4x_cpus_map=0,1,2,3,4,... // l4x_cpus_map=0,1,2,3,4,...
// the list specifies the physical CPU for each // the list specifies the physical CPU for each
@@ -1947,10 +1987,12 @@ @@ -1947,10 +1988,12 @@
LOG_printf("ERROR: Error parsing l4x_cpus_map option\n"); LOG_printf("ERROR: Error parsing l4x_cpus_map option\n");
return 1; return 1;
} }
@ -913,7 +868,7 @@ Index: arch/l4/kernel/main.c
l4x_cpu_physmap[l4x_nr_cpus].phys_id = pcpu; l4x_cpu_physmap[l4x_nr_cpus].phys_id = pcpu;
for (i = 0; i < l4x_nr_cpus; ++i) for (i = 0; i < l4x_nr_cpus; ++i)
overbooking |= overbooking |=
@@ -1974,12 +2016,16 @@ @@ -1974,12 +2017,16 @@
l4x_nr_cpus = v; l4x_nr_cpus = v;
} }
@ -930,7 +885,7 @@ Index: arch/l4/kernel/main.c
if (l4_error(l4_scheduler_info(l4re_env()->scheduler, if (l4_error(l4_scheduler_info(l4re_env()->scheduler,
&max_cpus, &cs)) == L4_EOK) { &max_cpus, &cs)) == L4_EOK) {
@@ -1989,6 +2035,8 @@ @@ -1989,6 +2036,8 @@
l4x_cpu_physmap[0].phys_id = p; l4x_cpu_physmap[0].phys_id = p;
} }
#endif #endif
@ -939,7 +894,7 @@ Index: arch/l4/kernel/main.c
LOG_printf("CPU mapping (l:p)[%d]: ", l4x_nr_cpus); LOG_printf("CPU mapping (l:p)[%d]: ", l4x_nr_cpus);
for (i = 0; i < l4x_nr_cpus; i++) for (i = 0; i < l4x_nr_cpus; i++)
@@ -2034,6 +2082,7 @@ @@ -2034,6 +2083,7 @@
printk("panic: going to sleep forever, bye\n"); printk("panic: going to sleep forever, bye\n");
L4XV_L(f); L4XV_L(f);
LOG_printf("panic: going to sleep forever, bye\n"); LOG_printf("panic: going to sleep forever, bye\n");
@ -947,7 +902,7 @@ Index: arch/l4/kernel/main.c
l4_sleep_forever(); l4_sleep_forever();
return 0; return 0;
} }
@@ -2302,7 +2351,7 @@ @@ -2302,7 +2352,7 @@
LOG_printf("Device scan done.\n"); LOG_printf("Device scan done.\n");
} }
@ -956,7 +911,7 @@ Index: arch/l4/kernel/main.c
{ {
l4lx_thread_t main_id; l4lx_thread_t main_id;
struct l4lx_thread_start_info_t si; struct l4lx_thread_start_info_t si;
@@ -2414,10 +2463,13 @@ @@ -2414,10 +2464,13 @@
l4x_start_thread_id = l4re_env()->main_thread; l4x_start_thread_id = l4re_env()->main_thread;
@ -970,7 +925,7 @@ Index: arch/l4/kernel/main.c
#ifndef CONFIG_L4_VCPU #ifndef CONFIG_L4_VCPU
#ifdef CONFIG_L4_TAMED #ifdef CONFIG_L4_TAMED
@@ -3223,6 +3275,10 @@ @@ -3223,6 +3276,10 @@
/* Not resolvable: Ooops */ /* Not resolvable: Ooops */
LOG_printf("Non-resolvable page fault at %lx, ip %lx.\n", pfa, ip); LOG_printf("Non-resolvable page fault at %lx, ip %lx.\n", pfa, ip);
// will trigger an oops in caller // will trigger an oops in caller
@ -981,7 +936,7 @@ Index: arch/l4/kernel/main.c
return 0; return 0;
} }
@@ -3419,7 +3475,9 @@ @@ -3419,7 +3476,9 @@
void exit(int code) void exit(int code)
{ {
__cxa_finalize(0); __cxa_finalize(0);
@ -991,6 +946,69 @@ Index: arch/l4/kernel/main.c
LOG_printf("Still alive, going zombie???\n"); LOG_printf("Still alive, going zombie???\n");
l4_sleep_forever(); l4_sleep_forever();
} }
Index: arch/l4/kernel/tamed.c
===================================================================
--- arch/l4/kernel/tamed.c (revision 25)
+++ arch/l4/kernel/tamed.c (working copy)
@@ -366,8 +366,12 @@
#ifdef CONFIG_L4_VCPU
void l4x_global_halt(void)
{
- l4vcpu_halt(l4x_vcpu_state_current(), l4x_utcb_current(),
- do_vcpu_irq, l4x_srv_setup_recv_wrap);
+ l4vcpu_wait_for_event(l4x_vcpu_state_current(), l4x_utcb_current(),
+ do_vcpu_irq, l4x_srv_setup_recv_wrap);
+#ifdef CONFIG_X86
+ // on x86, interrupts are enabled after hlt
+ l4x_global_sti();
+#endif
}
EXPORT_SYMBOL(l4x_global_halt);
Index: arch/l4/kernel/dispatch.c
===================================================================
--- arch/l4/kernel/dispatch.c (revision 25)
+++ arch/l4/kernel/dispatch.c (working copy)
@@ -121,6 +121,9 @@
{
unsigned long devmem;
+ printk("l4x_handle_dev_mem(%lx) called - currently not supported on Genode.\n", phy);
+ return 0;
+
#ifdef CONFIG_X86
if (phy > 0x80000000U) {
if (!(devmem = find_ioremap_entry(phy))
@@ -271,7 +274,7 @@
return 0;
if (l4_msgtag_is_page_fault(tag)) {
- l4x_printf("HYBRID PF!!\n");
+ LOG_printf("HYBRID PF!!\n");
/* No exception IPC, it's a page fault, but shouldn't happen */
goto out_fail;
}
@@ -695,7 +698,7 @@
enter_kdebug("non hybrid in idle?!");
} else {
if (unlikely(l4x_handle_async_event(label, utcb, tag)))
- l4x_printf("Async return with error\n");
+ LOG_printf("Async return with error\n");
}
}
}
Index: arch/l4/include/asm/arch-arm/pgtable.h
===================================================================
--- arch/l4/include/asm/arch-arm/pgtable.h (revision 25)
+++ arch/l4/include/asm/arch-arm/pgtable.h (working copy)
@@ -42,6 +42,7 @@
#include <asm/api/api.h>
+#define VMALLOC_OFFSET (8*1024*1024)
#define VMALLOC_SIZE 128
#define VMALLOC_START l4x_vmalloc_memory_start
Index: arch/l4/include/asm/generic/l4lib.h Index: arch/l4/include/asm/generic/l4lib.h
=================================================================== ===================================================================
--- arch/l4/include/asm/generic/l4lib.h (revision 25) --- arch/l4/include/asm/generic/l4lib.h (revision 25)
@ -1025,6 +1043,92 @@ Index: arch/l4/include/asm/l4lxapi/thread.h
/** /**
* \brief Create a thread. * \brief Create a thread.
* \ingroup thread * \ingroup thread
Index: arch/l4/boot/Makefile
===================================================================
--- arch/l4/boot/Makefile (revision 25)
+++ arch/l4/boot/Makefile (working copy)
@@ -10,7 +10,7 @@
$(call if_changed,objcopy)
@echo ' Kernel: $@ is ready'
-lImage: $(obj)/Image vmlinuz$(VMLINUZ_SUFFIX) l4linux$(VMLINUZ_SUFFIX)
+lImage: $(obj)/Image
vmlinuz$(VMLINUZ_SUFFIX): ldrImage FORCE
$(call if_changed,gzip)
@@ -21,8 +21,8 @@
objects-y := ldr.o res.o image.o
-include $(L4OBJ)/l4defs.mk.inc
-
+#include $(L4OBJ)/l4defs.mk.inc
+KBUILD_CFLAGS_i386 = -m32
KBUILD_CFLAGS := $(filter-out -mregparm=3,$(KBUILD_CFLAGS)) \
$(L4INC) -I$(L4OBJ)/include/uclibc \
-Wall -fno-strict-aliasing -O2 -pipe \
Index: arch/l4/lib/pte.c
===================================================================
--- arch/l4/lib/pte.c (revision 25)
+++ arch/l4/lib/pte.c (working copy)
@@ -18,7 +18,10 @@
#include <l4/sys/task.h>
#include <l4/sys/kdebug.h>
#include <l4/re/consts.h>
+#include <l4/log/log.h>
+extern void l4lx_memory_map_physical_page(unsigned long address);
+
static void l4x_flush_page(struct mm_struct *mm,
unsigned long address,
unsigned long vaddr,
@@ -45,6 +48,12 @@
}
} else
#endif
+#ifdef NOT_GENODE
+ /*
+ * Device memory is currently not supported on Genode. If this changes,
+ * a check for overlapping 'low memory' and 'device memory' regions
+ * must get added.
+ */
if (address > 0x80000000UL) {
unsigned long remap;
remap = find_ioremap_entry(address);
@@ -57,8 +66,10 @@
return;
address = remap;
+ } else
+#endif /* NOT_GENODE */
- } else if ((address & PAGE_MASK) == 0)
+ if ((address & PAGE_MASK) == 0)
address = PAGE0_PAGE_ADDRESS;
#if 0
@@ -77,7 +88,7 @@
if (mm && !l4_is_invalid_cap(mm->context.task)) {
L4XV_V(f);
if (!mm->context.task)
- l4x_printf("%s: Ups, task == 0\n", __func__);
+ LOG_printf("%s: Ups, task == 0\n", __func__);
/* Direct flush in the child, use virtual address in the
* child address space */
L4XV_L(f);
@@ -93,10 +104,11 @@
tag = l4_task_unmap(L4RE_THIS_TASK_CAP,
l4_fpage(address & PAGE_MASK, size, flush_rights),
L4_FP_OTHER_SPACES);
+ l4lx_memory_map_physical_page(address);
L4XV_U(f);
}
if (l4_error(tag))
- l4x_printf("l4_task_unmap error %ld\n", l4_error(tag));
+ LOG_printf("l4_task_unmap error %ld\n", l4_error(tag));
}
#ifdef ARCH_arm
Index: arch/x86/lib/memcpy_32.c Index: arch/x86/lib/memcpy_32.c
=================================================================== ===================================================================
--- arch/x86/lib/memcpy_32.c (revision 25) --- arch/x86/lib/memcpy_32.c (revision 25)
@ -1158,57 +1262,3 @@ Index: include/asm-generic/vmlinux.lds.h
. = ALIGN((align)); \ . = ALIGN((align)); \
VMLINUX_SYMBOL(__end_rodata) = .; \ VMLINUX_SYMBOL(__end_rodata) = .; \
} \ } \
Index: arch/l4/kernel/tamed.c
===================================================================
--- arch/l4/kernel/tamed.c (revision 25)
+++ arch/l4/kernel/tamed.c (working copy)
@@ -366,8 +366,12 @@
#ifdef CONFIG_L4_VCPU
void l4x_global_halt(void)
{
- l4vcpu_halt(l4x_vcpu_state_current(), l4x_utcb_current(),
- do_vcpu_irq, l4x_srv_setup_recv_wrap);
+ l4vcpu_wait_for_event(l4x_vcpu_state_current(), l4x_utcb_current(),
+ do_vcpu_irq, l4x_srv_setup_recv_wrap);
+#ifdef CONFIG_X86
+ // on x86, interrupts are enabled after hlt
+ l4x_global_sti();
+#endif
}
EXPORT_SYMBOL(l4x_global_halt);
Index: arch/l4/kernel/arch-x86/rtc.c
===================================================================
--- arch/l4/kernel/arch-x86/rtc.c (revision 25)
+++ arch/l4/kernel/arch-x86/rtc.c (working copy)
@@ -163,6 +163,7 @@
/* Routines for accessing the CMOS RAM/RTC. */
unsigned char rtc_cmos_read(unsigned char addr)
{
+#ifdef NOT_GENODE
#ifndef CONFIG_L4_EXTERNAL_RTC
unsigned char val;
@@ -175,17 +176,22 @@
#else
return 0;
#endif
+#else /* NOT_GENODE */
+ return 0;
+#endif /* NOT_GENODE */
}
EXPORT_SYMBOL(rtc_cmos_read);
void rtc_cmos_write(unsigned char val, unsigned char addr)
{
+#ifdef NOT_GENODE
#ifndef CONFIG_L4_EXTERNAL_RTC
lock_cmos_prefix(addr);
outb(addr, RTC_PORT(0));
outb(val, RTC_PORT(1));
lock_cmos_suffix(addr);
#endif
+#endif /* NOT_GENODE */
}
EXPORT_SYMBOL(rtc_cmos_write);

View File

@ -71,7 +71,12 @@ extern "C" {
Io_mem_connection *iomem = new (env()->heap()) Io_mem_connection(phys, size); Io_mem_connection *iomem = new (env()->heap()) Io_mem_connection(phys, size);
L4lx::Dataspace *ds = L4lx::Dataspace *ds =
L4lx::Env::env()->dataspaces()->insert("iomem", iomem->dataspace()); L4lx::Env::env()->dataspaces()->insert("iomem", iomem->dataspace());
L4lx::Env::env()->rm()->attach_at(ds, size, 0, (void*)virt); if (!L4lx::Env::env()->rm()->attach_at(ds, size, 0, (void*)virt)) {
PERR("Could not reserve IO mem region at %lx", virt);
L4lx::Env::env()->dataspaces()->remove(ds);
destroy(env()->heap(), iomem);
return 1;
}
return 0; return 0;
} }

View File

@ -27,8 +27,10 @@ namespace Fiasco {
using namespace Fiasco; using namespace Fiasco;
static const bool DEBUG = false; /* print usage of region map functions */ static const bool DEBUG = false; /* print usage of region map functions */
static const bool DEBUG_FIND = false; /* print also usage of region map lookups */ static const bool DEBUG_FIND = false; /* print also usage of region map lookups */
static const bool DEBUG_SEARCH = false; /* print also information about the
search for alternative address ranges */
enum { enum {
L4RE_SEARCH_FOR_REGION = 0x20, L4RE_SEARCH_FOR_REGION = 0x20,
@ -67,8 +69,10 @@ extern "C" {
{ {
using namespace Genode; using namespace Genode;
void *original_start = *start;
if (DEBUG) if (DEBUG)
PDBG("start=%p size=%lx flags=%lx mem=%lx offs=%lx align=%x", PDBG("start=%p size=%lx flags=%lx mem=%lx offs=%lx align=%u",
*start, size, flags, mem, offs, align); *start, size, flags, mem, offs, align);
L4lx::Dataspace *ds = L4lx::Env::env()->dataspaces()->find_by_ref(mem); L4lx::Dataspace *ds = L4lx::Env::env()->dataspaces()->find_by_ref(mem);
@ -77,11 +81,30 @@ extern "C" {
return -L4_ERANGE; return -L4_ERANGE;
} }
if(!L4lx::Env::env()->rm()->attach_at(ds, size, offs, *start)) { while (!L4lx::Env::env()->rm()->attach_at(ds, size, offs, *start)) {
if (flags & L4RE_SEARCH_FOR_REGION) /* search flag */ if (flags & L4RE_SEARCH_FOR_REGION) /* search flag */ {
*start = L4lx::Env::env()->rm()->attach(ds); /* the original start address might have a different alignment */
else { l4_addr_t start_addr = (l4_addr_t)*start;
PWRN("Couldn't attach ds of size %lx at %p", size, *start); l4_addr_t aligned_start_addr = align_addr(start_addr, align);
if (aligned_start_addr != start_addr) {
if (DEBUG_SEARCH)
PDBG("attach failed: start=%lx, trying %lx instead",
start_addr, aligned_start_addr);
*start = (void*)aligned_start_addr;
} else {
if (start_addr <= ((addr_t)~0 - 2*(1 << align) + 1)) {
if (DEBUG_SEARCH)
PDBG("attach failed: start=%lx, trying %lx instead",
start_addr, start_addr + (1 << align));
start_addr += (1 << align);
*start = (void*)start_addr;
} else {
PWRN("Couldn't attach ds of size 0x%lx at %p", size, original_start);
return -L4_ERANGE;
}
}
} else {
PWRN("Couldn't attach ds of size 0x%lx at %p", size, original_start);
return -L4_ERANGE; return -L4_ERANGE;
} }
} }
@ -116,7 +139,7 @@ extern "C" {
unsigned flags, unsigned char align) unsigned flags, unsigned char align)
{ {
if (DEBUG) if (DEBUG)
PDBG("*start=%lx size=%lx align=%x flags=%x", PDBG("*start=%lx size=%lx align=%u flags=%x",
*start, size, align, flags); *start, size, align, flags);
L4lx::Region *r = L4lx::Env::env()->rm()->reserve_range(size, align, *start); L4lx::Region *r = L4lx::Env::env()->rm()->reserve_range(size, align, *start);

View File

@ -15,6 +15,7 @@
#include <base/printf.h> #include <base/printf.h>
#include <rm_session/connection.h> #include <rm_session/connection.h>
#include <base/capability.h> #include <base/capability.h>
#include <util/misc_math.h>
/* L4lx includes */ /* L4lx includes */
#include <env.h> #include <env.h>
@ -27,6 +28,8 @@ namespace Fiasco {
using namespace L4lx; using namespace L4lx;
static const bool DEBUG_SEARCH = false; /* print information about the search
for alternative address ranges */
Region* Region_manager::find_region(Genode::addr_t *addr, Genode::size_t *size) Region* Region_manager::find_region(Genode::addr_t *addr, Genode::size_t *size)
{ {
@ -85,12 +88,6 @@ bool Region_manager::attach_at(Dataspace *ds, Genode::size_t size,
Genode::env()->rm_session()->attach(ds->cap(), size, offset, Genode::env()->rm_session()->attach(ds->cap(), size, offset,
true, (Genode::addr_t) addr); true, (Genode::addr_t) addr);
} catch(...) { } catch(...) {
/*
* This should happen only when Linux uses some special address,
* already used by Genode's heap, for instance some iomem for
* a directly used device.
*/
PERR("Region conflict at %p", addr);
return false; return false;
} }
metadata(addr, Region((Genode::addr_t)addr, ds->size(), ds)); metadata(addr, Region((Genode::addr_t)addr, ds->size(), ds));
@ -103,25 +100,48 @@ Region* Region_manager::reserve_range(Genode::size_t size, int align,
{ {
using namespace Genode; using namespace Genode;
void* addr = 0; void* addr = 0;
addr_t original_start = start;
while (true) { while (true) {
Rm_connection *rmc = 0;
try { try {
/* /*
* We attach a managed-dataspace as a placeholder to * We attach a managed-dataspace as a placeholder to
* Genode's region-map * Genode's region-map
*/ */
Rm_connection *rmc = new (env()->heap()) Rm_connection(0, size); rmc = new (env()->heap()) Rm_connection(0, size);
addr = start ? env()->rm_session()->attach_at(rmc->dataspace(), start) addr = start ? env()->rm_session()->attach_at(rmc->dataspace(), start)
: env()->rm_session()->attach(rmc->dataspace()); : env()->rm_session()->attach(rmc->dataspace());
//PDBG("attach done addr=%p!", addr); //PDBG("attach done addr=%p!", addr);
break; break;
} catch(Rm_session::Attach_failed e) { } catch(Rm_session::Attach_failed e) {
PWRN("attach failed start=%lx", start); destroy(env()->heap(), rmc);
if (start) /* attach with pre-defined address failed, so search one */ /* attach with pre-defined address failed, so search one */
start = 0; if (start) {
else /* the original start address might have a different alignment */
addr_t aligned_start = align_addr(start, align);
if (aligned_start != start) {
if (DEBUG_SEARCH)
PDBG("attach failed: start=%lx, trying %lx instead",
start, aligned_start);
start = aligned_start;
} else {
if (start <= ((addr_t)~0 - 2*(1 << align) + 1)) {
if (DEBUG_SEARCH)
PDBG("attach failed: start=%lx, trying %lx instead",
start, start + (1 << align));
start += (1 << align);
} else {
PWRN("attach failed: start=%lx, size=0x%zx, align=%d", original_start, size, align);
return 0;
}
}
} else {
PWRN("attach failed: start=0, size=0x%zx, align=%d", size, align);
return 0; return 0;
}
} }
} }