Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/l4test enhancement #140

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/l4/kip_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
2 changes: 2 additions & 0 deletions user/apps/l4test/build.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
user-apps-l4test-y = \
string.o \
ipc.o \
kip.o \
mem.o \
assert.o \
main.o \
60 changes: 59 additions & 1 deletion user/apps/l4test/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use consistent coding style.

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;
Expand Down Expand Up @@ -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);
Expand Down
292 changes: 292 additions & 0 deletions user/apps/l4test/kip.c
Original file line number Diff line number Diff line change
@@ -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 <l4/ipc.h>
#include <l4/kip.h>
#include <l4/space.h>
#include <l4/thread.h>
#include <l4/arch.h>
#include <l4/kdebug.h>
#include <l4/pager.h>
#include <l4io.h>
#include <platform/cortex_m.h>

#include "arch.h"
#include "config.h"
#include "l4test.h"
#include "assert.h"

__USER_TEXT
int check_kipptr(L4_KernelInterfacePage_t *kip, void * ptr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We prefer void *ptr over void * ptr.

{
if (((L4_Word_t)kip + (1 << kip->KipAreaInfo.X.s) >= (L4_Word_t)ptr)
&& (ptr >= (void *) kip))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check coding style.

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[] =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't really want to implement full KernelInformation support. Use dummy array instead.

{
{ 0, 0, "F9", "NCKU" },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

F9 is an independent project from 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();
}
Loading