From e486d1d22150514c0b85248bd9d855b988bc0aa2 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Sun, 20 Nov 2016 14:46:34 +0800 Subject: [PATCH 1/3] TODO: must implement kip_kern_desc_t --- include/l4/kip_types.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/l4/kip_types.h b/include/l4/kip_types.h index e0e67edb..0a4b6917 100644 --- a/include/l4/kip_types.h +++ b/include/l4/kip_types.h @@ -61,6 +61,12 @@ struct kip { uint32_t kernel_id; kip_apiversion_t api_version; kip_apiflags_t api_flags; + + /* + * TODO: Fixed kern desc ptr to L4 reference manual style. + * Also, fixed kenrel_id to magic, and change + * L4_KernelInterface in userspace behavior. + */ uint32_t kern_desc_ptr; uint32_t reserved1[17]; From 630c1e5391b685e4f0c41abcd48002a17ff8fad9 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Sun, 20 Nov 2016 14:51:14 +0800 Subject: [PATCH 2/3] l4test: Add KIP test cases --- user/apps/l4test/build.mk | 1 + user/apps/l4test/kip.c | 292 ++++++++++++++++++++++++++++++++ user/apps/l4test/l4test.h | 2 +- user/apps/l4test/main.c | 16 +- user/lib/l4/platform/syscalls.c | 5 + 5 files changed, 311 insertions(+), 5 deletions(-) create mode 100644 user/apps/l4test/kip.c diff --git a/user/apps/l4test/build.mk b/user/apps/l4test/build.mk index 7521ac4e..eba602bc 100644 --- a/user/apps/l4test/build.mk +++ b/user/apps/l4test/build.mk @@ -5,5 +5,6 @@ user-apps-l4test-y = \ string.o \ ipc.o \ + kip.o \ assert.o \ main.o \ diff --git a/user/apps/l4test/kip.c b/user/apps/l4test/kip.c new file mode 100644 index 00000000..1aedea1d --- /dev/null +++ b/user/apps/l4test/kip.c @@ -0,0 +1,292 @@ +/* Copyright (c) 2002, 2003, 2007, 2010 Karlsruhe University. + * All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "arch.h" +#include "config.h" +#include "l4test.h" +#include "assert.h" + +__USER_TEXT +int check_kipptr(L4_KernelInterfacePage_t *kip, void * ptr) +{ + if (((L4_Word_t)kip + (1 << kip->KipAreaInfo.X.s) >= (L4_Word_t)ptr) + && (ptr >= (void *) kip)) + return 1; + printf("ERROR: kip-ptr (%p) not within KIP area\n", ptr); + return 0; +} + +/* list of kernel ids, subids and what they are */ +typedef struct kid_list_t { + L4_Word_t id; + L4_Word_t subid; + const char *kernel; + const char * supplier; +} kid_list_t; + +__USER_DATA +kid_list_t kid_list[] = +{ + { 0, 0, "F9", "NCKU" }, + { 0, 1, "L4/486", "GMD" }, + { 0, 2, "L4/Pentium", "IBM" }, + { 0, 3, "L4/x86", "UKa" }, + { 1, 1, "L4/Mips", "UNSW" }, + { 2, 1, "L4/Alpha", "TUD, UNSW" }, + { 3, 1, "Fiasco", "TUD" }, + { 4, 1, "L4Ka/Hazelnut", "UKa" }, + { 4, 2, "L4Ka/Pistachio", "UKa" }, + { 4, 3, "L4Ka/Strawberry", "UKa" }, +}; +#define KID_LIST_COUNT (sizeof(kid_list)/sizeof(kid_list[0])) + +/* list of API versions */ +#define NO_SUBVERSION (L4_Word_t)-1ULL +typedef struct api_list_t { + L4_Word_t version; + L4_Word_t subversion; + const char *api; +} api_list_t; + +__USER_DATA +api_list_t api_list[] = +{ + { L4_APIVERSION_2, NO_SUBVERSION, "Version 2" }, + { L4_APIVERSION_X0, L4_APISUBVERSION_X0, "Experimental Version X.0" }, + { L4_APIVERSION_X1, L4_APISUBVERSION_X1, "Experimental Version X.1" }, + { L4_APIVERSION_X2, NO_SUBVERSION, "Experimental Version X.2" }, + { L4_APIVERSION_4, NO_SUBVERSION, "Version 4" }, +}; +#define API_LIST_COUNT (sizeof(api_list)/sizeof(api_list[0])) + +/* assume these could have 2 * 3 filled in later */ +__USER_DATA const char *endianess[] = {"little", "big", "ERROR-2", "ERROR-3"}; +__USER_DATA const char *apiwidth [] = {"32-bit", "64-bit", "ERROR-2", "ERROR-3"}; + +#define TAG0 0 +#define TAG1 1 +#define TAG2 2 +#define TAG3 3 + +/* other module functions */ +__USER_TEXT +void print_kernelid(L4_Word_t kid_w) +{ + L4_KernelId_t kid; + L4_Word_t i; + const char *kernel, *supplier; + + kid.raw = kid_w; + + for (i = 0; i < KID_LIST_COUNT; ++i) { + if ((kid_list[i].id == kid.x.id) && + (kid_list[i].subid == kid.x.subid)) { + break; + } + } + + if (i != KID_LIST_COUNT) { + kernel = kid_list[i].kernel; + supplier = kid_list[i].supplier; + } else { + kernel = "unknown kernel"; + supplier = "unknow supplier"; + } + + printf("KernelID reports 0x%x.0x%x: %s from %s\n", + (long) kid.x.id, (long) kid.x.subid, + kernel, supplier); +} + +__USER_TEXT +void print_version(L4_Word_t apiv) +{ + L4_ApiVersion_t api; + L4_Word_t i; + const char *version; + + api.raw = apiv; + + for (i = 0; i < API_LIST_COUNT; ++i) { + if ((api.x.version == api_list[i].version) && + ((api.x.subversion == api_list[i].subversion) || + (api_list[i].subversion == NO_SUBVERSION))) { + break; + } + } + + if (i != API_LIST_COUNT) { + version = api_list[i].api; + } else { + version = "unknow api"; + } + + printf("APIVersion reports %d.%d: %s\n", + (int) api.x.version, (int) api.x.subversion, + version); +} + +__USER_TEXT +void print_apiflags(L4_Word_t apif) +{ + L4_ApiFlags_t api; + + api.raw = apif; + + printf("APIFlags reports %s endianess\n", endianess[api.x.ee]); + printf("APIFlags reports %s API width\n", apiwidth [api.x.ww]); +} + + +__USER_TEXT +void print_alignment(void *kip) +{ + L4_Word_t kipw = (L4_Word_t) kip; + printf("KIP alignment %s OK\n", + (kipw == (kipw & PAGE_MASK)) ? "is" : "IS NOT"); +} + +__USER_TEXT +void print_l4tag(L4_KernelInterfacePage_t *kip) +{ + char *tag = (char *) kip; + printf("L4tag is: %c%c%c%c\n", + tag[TAG0], tag[TAG1], tag[TAG2], tag[TAG3]); + + printf( "L4tag %s valid\n", + ((*(L4_Word32_t*)tag) & 0xffffffff) == L4_MAGIC ? + "is" : "IS NOT"); +} + +__USER_TEXT +void print_infos(L4_KernelInterfacePage_t * kip) +{ + printf("Threads: IRQs=%ld, sys=%ld, valid TID bits=%ld\n", + L4_ThreadIdSystemBase(kip), + L4_ThreadIdUserBase(kip) - L4_ThreadIdSystemBase(kip), + L4_ThreadIdBits(kip)); +} + +__USER_TEXT +void print_kerndesc( L4_KernelInterfacePage_t * kip ) +{ + L4_KernelDesc_t * desc; + if (!kip->KernelVerPtr) { + printf("KernelVerPtr is invalid (%p)\n", L4_KernelVersionString (kip)); + return; + } + + /* FIXME: Not test yet */ + desc = (L4_KernelDesc_t*)((L4_Word_t)kip + kip->KernelVerPtr); + + if (!check_kipptr(kip, desc)) + return; + + L4_Word_t year, month, day; + L4_KernelGenDate (kip, &year, &month, &day); + print_kernelid(desc->KernelId.raw); + printf("Kernel generation date: %ld/%ld/%ld\n", day, month, year); + printf("Kernel Version: %ld.%ld.%ld\n", desc->KernelVer.X.ver, + desc->KernelVer.X.subver, desc->KernelVer.X.subsubver); + + char * sup = (char*)&desc->Supplier; + printf("Supplier string: \"%c%c%c%c\"\n", sup[0], sup[1], sup[2], sup[3]); + printf("Version string: \"%s\"\n", desc->VersionString); +} + +__USER_TEXT +void print_procdesc(L4_KernelInterfacePage_t * kip) +{ + int num = kip->ProcessorInfo.X.processors + 1; + printf("Processors: %d\n", num); + for (int cpu = 0; cpu < num; cpu++) { + L4_ProcDesc_t *pdesc = L4_ProcDesc(kip, cpu); + printf(" CPU%d: ", cpu); + if (check_kipptr(kip, pdesc)) { + printf("int freq=%ldkHz, ext freq=%ldkHz\n", + L4_ProcDescInternalFreq (pdesc), + L4_ProcDescExternalFreq (pdesc)); + } else { + printf("invalid descriptor\n"); + } + } +} + +__USER_TEXT +static void print_kip(void) +{ + void *kip; + L4_KernelInterfacePage_t *skip; + L4_Word_t apiv, apif, kid; + + kip = L4_KernelInterface(&apiv, &apif, &kid); + print_h1("Kernel Interface Page"); + + /* dump what we got in registers */ + print_kernelid(kid); + print_version(apiv); + print_apiflags(apif); + + printf("Address of KIP is %p\n", kip); + print_alignment(kip); + + /* dump what we find in memory */ + print_h2("KIP memory values"); + skip = (L4_KernelInterfacePage_t *) kip; + print_l4tag(skip); + + print_version(skip->ApiVersion.raw); + print_apiflags(skip->ApiFlags.raw); + print_infos(skip); + + print_kerndesc(skip); /* Unimplemented descriptor */ + print_procdesc(skip); /* Unimplemented descriptor */ +} + +__USER_TEXT +static void call_kip(int depth) +{ + void *kip; + L4_Word_t apiv, apif, kid; + + if(depth == 0) + kip = L4_KernelInterface(&apiv, &apif, &kid); + else + call_kip( depth - 1 ); + + /* Because our compiler told us we set `kip` but not used*/ + kip = kip; +} + +__USER_TEXT +static void thrash_kip(void) +{ + int i, j; + + for(j = 0; j < 10; j++) { + printf("Checking KIP, depth %d\n", j); + + for(i = 0; i < 1000; i++) + call_kip(j); + } +} + +__USER_TEXT +void all_kip_tests(void) +{ + print_kip(); + thrash_kip(); +} diff --git a/user/apps/l4test/l4test.h b/user/apps/l4test/l4test.h index 5eeec085..26f9739e 100644 --- a/user/apps/l4test/l4test.h +++ b/user/apps/l4test/l4test.h @@ -8,7 +8,7 @@ #define __L4TEST_H__ /* define this for ANSI menus */ -//#define USE_ANSI 1 +#define USE_ANSI 1 #include #include "string.h" #include diff --git a/user/apps/l4test/main.c b/user/apps/l4test/main.c index 2b48cb98..d3f1b401 100644 --- a/user/apps/l4test/main.c +++ b/user/apps/l4test/main.c @@ -26,6 +26,7 @@ __USER_BSS static char *free_page; /* colours */ +__USER_TEXT static void set_colour(const char *col) { @@ -34,10 +35,15 @@ set_colour(const char *col) #endif } -void +__USER_TEXT void print_uline(const char *msg, char c) { - int i, len = strlen(msg); + /* + * TODO: Why can't we use strlen, the string memory was + * protected by MPU...... my friend. When you use + * strlen, it just trigger panic by MPU. + */ + int i, len = 25; /* This bad guy, strlen(msg) cause panic */ printf("%s\n", msg); @@ -46,7 +52,7 @@ print_uline(const char *msg, char c) putc('\n'); } -void +__USER_TEXT void print_h1(const char *msg) { set_colour(LIGHT_BLUE); @@ -54,7 +60,7 @@ print_h1(const char *msg) set_colour(BLACK); } -void +__USER_TEXT void print_h2(const char *msg) { set_colour(LIGHT_RED); @@ -149,8 +155,10 @@ msec_sleep(L4_Word_t msec) __USER_TEXT void all_tests(void) { + extern void all_kip_tests(void); extern void all_ipc_tests(void); + all_kip_tests(); all_ipc_tests(); } diff --git a/user/lib/l4/platform/syscalls.c b/user/lib/l4/platform/syscalls.c index b36517e9..fd03f384 100644 --- a/user/lib/l4/platform/syscalls.c +++ b/user/lib/l4/platform/syscalls.c @@ -7,6 +7,7 @@ #include #include +#include #include #include __L4_INC_ARCH(syscalls.h) @@ -15,6 +16,10 @@ void *L4_KernelInterface(L4_Word_t *ApiVersion, L4_Word_t *ApiFlags, L4_Word_t *KernelId) { + L4_KernelInterfacePage_t *skip = (L4_KernelInterfacePage_t *) &kip_start; + *ApiVersion = skip->ApiVersion.raw; + *ApiFlags = skip->ApiFlags.raw; + *KernelId = skip->magic; return &kip_start; } From b1b7091d28191b02a338145d4bdba889593c56cf Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Sun, 20 Nov 2016 22:41:59 +0800 Subject: [PATCH 3/3] l4test: Update IPC test cases, Add mem test cases --- user/apps/l4test/build.mk | 1 + user/apps/l4test/ipc.c | 60 ++++++++++++++++++++++++++++++++++++++- user/apps/l4test/main.c | 2 ++ user/apps/l4test/mem.c | 39 +++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 user/apps/l4test/mem.c diff --git a/user/apps/l4test/build.mk b/user/apps/l4test/build.mk index eba602bc..33d953fd 100644 --- a/user/apps/l4test/build.mk +++ b/user/apps/l4test/build.mk @@ -6,5 +6,6 @@ user-apps-l4test-y = \ string.o \ ipc.o \ kip.o \ + mem.o \ assert.o \ main.o \ diff --git a/user/apps/l4test/ipc.c b/user/apps/l4test/ipc.c index 33d15848..5ce7a951 100644 --- a/user/apps/l4test/ipc.c +++ b/user/apps/l4test/ipc.c @@ -74,7 +74,7 @@ void setup_ipc_threads(void *(*f1)(void *), void *(*f2)(void *), } /* - ** IPC test with only untyped words + * IPC test with only untyped words */ __USER_TEXT static void *simple_ipc_t1_l(void *arg) @@ -172,6 +172,52 @@ static void *simple_ipc_t1_l(void *arg) } print_result("ReplyWait Message transfer", ipc_ok); + + /* Send timeout */ + L4_Set_MsgTag(L4_Niltag); + tag = L4_Send_Timeout(ipc_t2, L4_TimePeriod(1000 * 1000)); + ipc_ok = true; + + if (L4_IpcSucceeded(tag)) { + printf("SND: IPC send incorrectly succeeded\n"); + ipc_ok = false; + } else { + if ((L4_ErrorCode() & 0x1) || ((L4_ErrorCode() >> 1) & 0x7) != 1) { + printf("SND: Incorrect error code: %s %s\n", + ipc_errorcode(L4_ErrorCode()), + ipc_errorphase(L4_ErrorCode())); + ipc_ok = false; + } + } + print_result("Send timeout", ipc_ok); + L4_Receive(ipc_t2); + + /* Receive timeout */ + tag = L4_Receive_Timeout(ipc_t2, L4_TimePeriod(1000 * 1000)); + ipc_ok = true; + + if (L4_IpcSucceeded(tag)) { + printf("RCV: IPC receive incorrectly succeeded\n"); + ipc_ok = false; + } else { + if ((L4_ErrorCode() & 0x1) == 0 || + ((L4_ErrorCode() >> 1) & 0x7) != 1) { + printf ("RCV: Incorrect error code: %s %s\n", + ipc_errorcode (L4_ErrorCode ()), + ipc_errorphase (L4_ErrorCode ())); + ipc_ok = false; + } + } + print_result("Receive timeout", ipc_ok); + L4_Set_MsgTag(L4_Niltag); + L4_Send(ipc_t2); + + /* Local destination Id */ + tag = L4_Receive_Timeout(ipc_t2, L4_TimePeriod(5 * 1000 * 1000)); + print_result("Local destination Id", L4_IpcSucceeded(tag)); + L4_Set_MsgTag(L4_Niltag); + tag = L4_Send(ipc_t2); + /* From parameter (local) */ tag = L4_Wait(&from); ipc_ok = true; @@ -237,6 +283,18 @@ static void *simple_ipc_t2_l(void *arg) } + /* Send timeout */ + L4_Set_MsgTag(L4_Niltag); + L4_Send(ipc_t1); + + /* Receive timeout */ + L4_Receive(ipc_t1); + + /* Local destination Id */ + L4_Set_MsgTag(L4_Niltag); + L4_Send(L4_LocalIdOf(ipc_t1)); + L4_Receive(ipc_t1); + // From parameter (local) L4_Set_MsgTag(L4_Niltag); L4_Send(ipc_t1); diff --git a/user/apps/l4test/main.c b/user/apps/l4test/main.c index d3f1b401..739522c5 100644 --- a/user/apps/l4test/main.c +++ b/user/apps/l4test/main.c @@ -157,8 +157,10 @@ __USER_TEXT void all_tests(void) { extern void all_kip_tests(void); extern void all_ipc_tests(void); + extern void all_mem_tests(void); all_kip_tests(); + all_mem_tests(); all_ipc_tests(); } diff --git a/user/apps/l4test/mem.c b/user/apps/l4test/mem.c new file mode 100644 index 00000000..b6fe53f1 --- /dev/null +++ b/user/apps/l4test/mem.c @@ -0,0 +1,39 @@ +/* Copyright (c) 2002, 2003, 2007, 2010 Karlsruhe University. + * All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include +#include +#include +#include + +#include "arch.h" +#include "config.h" +#include "l4test.h" +#include "assert.h" + +__USER_TEXT +static void page_touch(void) +{ + volatile L4_Word_t *addr = (L4_Word_t *) get_new_page(); + int n = 0; + int max = 1000; + + printf("test: Welcome to memtest!\n"); + + while (max--) { + // *addr = 0x37ULL; + addr += (PAGE_SIZE / sizeof(*addr)); + n++; + } + + print_result("Page touch", true); +} + +__USER_TEXT +void all_mem_tests(void) +{ + page_touch(); +}