Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3741 → Rev 3742

/branches/sparc/kernel/generic/include/udebug/udebug.h
177,9 → 177,9
 
/** What type of event are we stopped in or 0 if none. */
udebug_event_t cur_event;
bool go; /**< thread is GO */
bool stoppable; /**< thread is stoppable */
bool debug_active; /**< thread is in a debugging session */
bool go; /**< thread is GO */
bool stoppable; /**< thread is stoppable */
bool active; /**< thread is in a debugging session */
} udebug_thread_t;
 
struct task;
/branches/sparc/kernel/generic/include/debug.h
63,15 → 63,15
# define ASSERT(expr)
#endif
 
/** Extensive debugging output macro
/** Extensive logging output macro
*
* If CONFIG_EDEBUG is set, the LOG() macro
* If CONFIG_LOG is set, the LOG() macro
* will print whatever message is indicated plus
* an information about the location.
*
*/
 
#ifdef CONFIG_EDEBUG
#ifdef CONFIG_LOG
# define LOG(format, ...) \
printf("%s() at %s:%u: " format "\n", __func__, __FILE__, \
__LINE__, ##__VA_ARGS__);
79,15 → 79,15
# define LOG(format, ...)
#endif
 
/** Extensive debugging execute macro
/** Extensive logging execute macro
*
* If CONFIG_EDEBUG is set, the LOG_EXEC() macro
* If CONFIG_LOG is set, the LOG_EXEC() macro
* will print an information about calling a given
* function and call it.
*
*/
 
#ifdef CONFIG_EDEBUG
#ifdef CONFIG_LOG
# define LOG_EXEC(fnc) \
{ \
printf("%s() at %s:%u: " #fnc "\n", __func__, __FILE__, \
/branches/sparc/kernel/generic/include/console/kconsole.h
87,7 → 87,8
extern link_t cmd_head;
 
extern void kconsole_init(void);
extern void kconsole(void *prompt);
extern void kconsole(char *prompt, char *msg, bool kcon);
extern void kconsole_thread(void *data);
 
extern int cmd_register(cmd_info_t *cmd);
 
/branches/sparc/kernel/generic/include/macros.h
45,8 → 45,8
#define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || \
((c) == '\r'))
 
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
 
/** Return true if the intervals overlap.
*
/branches/sparc/kernel/generic/src/main/kinit.c
82,8 → 82,11
*/
void kinit(void *arg)
{
thread_t *t;
 
#if defined(CONFIG_SMP) || defined(CONFIG_KCONSOLE)
thread_t *thread;
#endif
 
/*
* Detach kinit as nobody will call thread_join_timeout() on it.
*/
100,23 → 103,19
* not mess together with kcpulb threads.
* Just a beautification.
*/
if ((t = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED,
"kmp", true))) {
spinlock_lock(&t->lock);
t->cpu = &cpus[0];
spinlock_unlock(&t->lock);
thread_ready(t);
thread = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, "kmp", true);
if (thread != NULL) {
spinlock_lock(&thread->lock);
thread->cpu = &cpus[0];
spinlock_unlock(&thread->lock);
thread_ready(thread);
} else
panic("thread_create/kmp\n");
thread_join(t);
thread_detach(t);
panic("Unable to create kmp thread\n");
thread_join(thread);
thread_detach(thread);
}
#endif /* CONFIG_SMP */
/*
* Now that all CPUs are up, we can report what we've found.
*/
cpu_list();
 
#ifdef CONFIG_SMP
if (config.cpu_count > 1) {
count_t i;
125,37 → 124,39
* For each CPU, create its load balancing thread.
*/
for (i = 0; i < config.cpu_count; i++) {
 
if ((t = thread_create(kcpulb, NULL, TASK,
THREAD_FLAG_WIRED, "kcpulb", true))) {
spinlock_lock(&t->lock);
t->cpu = &cpus[i];
spinlock_unlock(&t->lock);
thread_ready(t);
thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true);
if (thread != NULL) {
spinlock_lock(&thread->lock);
thread->cpu = &cpus[i];
spinlock_unlock(&thread->lock);
thread_ready(thread);
} else
panic("thread_create/kcpulb\n");
printf("Unable to create kcpulb thread for cpu" PRIc "\n", i);
 
}
}
#endif /* CONFIG_SMP */
 
/*
* At this point SMP, if present, is configured.
*/
arch_post_smp_init();
 
/*
* Create kernel console.
*/
t = thread_create(kconsole, (void *) "kconsole", TASK, 0, "kconsole",
false);
if (t)
thread_ready(t);
else
panic("thread_create/kconsole\n");
 
#ifdef CONFIG_KCONSOLE
if (stdin) {
/*
* Create kernel console.
*/
thread = thread_create(kconsole_thread, NULL, TASK, 0, "kconsole", false);
if (thread != NULL)
thread_ready(thread);
else
printf("Unable to create kconsole thread\n");
}
#endif /* CONFIG_KCONSOLE */
interrupts_enable();
/*
* Create user tasks, load RAM disk images.
*/
164,14 → 165,14
for (i = 0; i < init.cnt; i++) {
if (init.tasks[i].addr % FRAME_SIZE) {
printf("init[%" PRIc "].addr is not frame aligned", i);
printf("init[%" PRIc "].addr is not frame aligned\n", i);
continue;
}
 
int rc = program_create_from_image((void *) init.tasks[i].addr,
"init-bin", &programs[i]);
 
if (rc == 0 && programs[i].task != NULL) {
if ((rc == 0) && (programs[i].task != NULL)) {
/*
* Set capabilities to init userspace tasks.
*/
184,12 → 185,10
/* It was the program loader and was registered */
} else {
/* RAM disk image */
int rd = init_rd((rd_header_t *) init.tasks[i].addr,
init.tasks[i].size);
int rd = init_rd((rd_header_t *) init.tasks[i].addr, init.tasks[i].size);
if (rd != RE_OK)
printf("Init binary %" PRIc " not used, error "
"code %d.\n", i, rd);
printf("Init binary %" PRIc " not used (error %d)\n", i, rd);
}
}
203,12 → 202,18
}
}
 
#ifdef CONFIG_KCONSOLE
if (!stdin) {
printf("kinit: No stdin\nKernel alive: ");
uint64_t i = 0;
while (1) {
printf(PRIu64 " ", i);
thread_sleep(1);
printf("kinit... ");
i++;
}
}
#endif /* CONFIG_KCONSOLE */
}
 
/** @}
/branches/sparc/kernel/generic/src/main/main.c
191,8 → 191,6
{
/* Keep this the first thing. */
the_initialize(THE);
 
LOG();
version_print();
200,8 → 198,8
"\nconfig.stack_base=%#" PRIp " config.stack_size=%" PRIs,
config.base, config.kernel_size, config.stack_base,
config.stack_size);
 
#ifdef CONFIG_KCONSOLE
/*
* kconsole data structures must be initialized very early
* because other subsystems will register their respective
208,6 → 206,7
* commands.
*/
LOG_EXEC(kconsole_init());
#endif
/*
* Exception handler initialization, before architecture
252,7 → 251,7
if (init.cnt > 0) {
count_t i;
for (i = 0; i < init.cnt; i++)
printf("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc
LOG("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc
"].size=%#" PRIs "\n", i, init.tasks[i].addr, i,
init.tasks[i].size);
} else
271,8 → 270,8
/*
* Create the first thread.
*/
thread_t *kinit_thread = thread_create(kinit, NULL, kernel, 0, "kinit",
true);
thread_t *kinit_thread
= thread_create(kinit, NULL, kernel, 0, "kinit", true);
if (!kinit_thread)
panic("Can't create kinit thread\n");
LOG_EXEC(thread_ready(kinit_thread));
/branches/sparc/kernel/generic/src/cpu/cpu.c
86,7 → 86,7
}
#endif /* CONFIG_SMP */
 
CPU = &cpus[config.cpu_active-1];
CPU = &cpus[config.cpu_active - 1];
CPU->active = 1;
CPU->tlb_active = 1;
99,6 → 99,7
void cpu_list(void)
{
unsigned int i;
 
for (i = 0; i < config.cpu_count; i++) {
if (cpus[i].active)
cpu_print_report(&cpus[i]);
/branches/sparc/kernel/generic/src/interrupt/interrupt.c
109,8 → 109,10
panic("Unhandled exception %d.", n);
}
 
#ifdef CONFIG_KCONSOLE
 
/** kconsole cmd - print all exceptions */
static int exc_print_cmd(cmd_arg_t *argv)
static int cmd_exc_print(cmd_arg_t *argv)
{
#if (IVT_ITEMS > 0)
unsigned int i;
158,15 → 160,18
return 1;
}
 
 
static cmd_info_t exc_info = {
.name = "exc",
.description = "Print exception table.",
.func = exc_print_cmd,
.func = cmd_exc_print,
.help = NULL,
.argc = 0,
.argv = NULL
};
 
#endif
 
/** Initialize generic exception handling support */
void exc_init(void)
{
175,9 → 180,11
for (i = 0; i < IVT_ITEMS; i++)
exc_register(i, "undef", (iroutine) exc_undef);
 
#ifdef CONFIG_KCONSOLE
cmd_initialize(&exc_info);
if (!cmd_register(&exc_info))
panic("could not register command %s\n", exc_info.name);
printf("Cannot register command %s\n", exc_info.name);
#endif
}
 
/** @}
/branches/sparc/kernel/generic/src/time/clock.c
189,13 → 189,17
spinlock_unlock(&THREAD->lock);
if (!ticks && !PREEMPTION_DISABLED) {
#ifdef CONFIG_UDEBUG
istate_t *istate;
#endif
scheduler();
#ifdef CONFIG_UDEBUG
/*
* Give udebug chance to stop the thread
* before it begins executing.
* before it begins executing userspace code.
*/
if (istate_from_uspace(THREAD->udebug.uspace_state))
istate = THREAD->udebug.uspace_state;
if (istate && istate_from_uspace(istate))
udebug_before_thread_runs();
#endif
}
/branches/sparc/kernel/generic/src/console/console.c
167,7 → 167,7
printf("cpu%u: ", CPU->id);
else
printf("cpu: ");
printf("halted - no kconsole\n");
printf("halted (no kconsole)\n");
cpu_halt();
}
 
/branches/sparc/kernel/generic/src/console/cmd.c
501,7 → 501,7
for (i = 0; basic_commands[i]; i++) {
cmd_initialize(basic_commands[i]);
if (!cmd_register(basic_commands[i]))
panic("could not register command %s\n", basic_commands[i]->name);
printf("Cannot register command %s\n", basic_commands[i]->name);
}
}
 
/branches/sparc/kernel/generic/src/console/kconsole.c
401,11 → 401,15
return current;
}
 
/** Kernel console managing thread.
/** Kernel console prompt.
*
* @param prompt Kernel console prompt (e.g kconsole/panic).
* @param msg Message to display in the beginning.
* @param kcon Wait for keypress to show the prompt
* and never exit.
*
*/
void kconsole(void *prompt)
void kconsole(char *prompt, char *msg, bool kcon)
{
cmd_info_t *cmd_info;
count_t len;
412,25 → 416,42
char *cmdline;
 
if (!stdin) {
printf("%s: no stdin\n", __func__);
LOG("No stdin for kernel console");
return;
}
if (msg)
printf("%s", msg);
if (kcon)
_getc(stdin);
while (true) {
cmdline = clever_readline((char *) prompt, stdin);
len = strlen(cmdline);
if (!len)
continue;
cmd_info = parse_cmdline(cmdline, len);
if (!cmd_info)
continue;
if (strncmp(cmd_info->name, "exit",
min(strlen(cmd_info->name), 5)) == 0)
if ((!kcon)
&& (strncmp(cmd_info->name, "exit", min(strlen(cmd_info->name), 5)) == 0))
break;
(void) cmd_info->func(cmd_info->argv);
}
}
 
/** Kernel console managing thread.
*
*/
void kconsole_thread(void *data)
{
kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true);
}
 
static int parse_int_arg(char *text, size_t len, unative_t *result)
{
static char symname[MAX_SYMBOL_NAME];
/branches/sparc/kernel/generic/src/proc/thread.c
484,7 → 484,7
THREAD->state = Exiting;
spinlock_unlock(&THREAD->lock);
scheduler();
 
/* Not reached */
while (1)
;
/branches/sparc/kernel/generic/src/lib/func.c
55,8 → 55,6
#ifdef CONFIG_DEBUG
bool rundebugger = false;
 
// TODO test_and_set not defined on all arches
// if (!test_and_set(&haltstate))
if (!atomic_get(&haltstate)) {
atomic_set(&haltstate, 1);
rundebugger = true;
66,12 → 64,12
#endif
 
interrupts_disable();
#ifdef CONFIG_DEBUG
if (rundebugger) {
printf("\n");
kconsole("panic"); /* Run kconsole as a last resort to user */
}
#endif
#if (defined(CONFIG_DEBUG)) && (defined(CONFIG_KCONSOLE))
if (rundebugger)
kconsole("panic", "\nLast resort kernel console ready\n", false);
#endif
if (CPU)
printf("cpu%u: halted\n", CPU->id);
else
/branches/sparc/kernel/generic/src/mm/as.c
146,8 → 146,12
AS_KERNEL = as_create(FLAG_AS_KERNEL);
if (!AS_KERNEL)
panic("can't create kernel address space\n");
panic("Cannot create kernel address space\n");
/* Make sure the kernel address space
* reference count never drops to zero.
*/
atomic_set(&AS_KERNEL->refcount, 1);
}
 
/** Create address space.
176,7 → 180,7
#else
page_table_create(flags);
#endif
 
return as;
}
 
769,11 → 773,12
* In order for this to work properly, this may copy the data
* into private anonymous memory (unless it's already there).
*
* @param as Address space.
* @param flags Flags of the area memory.
* @param address Address withing the area to be changed.
* @param as Address space.
* @param flags Flags of the area memory.
* @param address Address within the area to be changed.
*
* @return Zero on success or a value from @ref errno.h on failure.
* @return Zero on success or a value from @ref errno.h on failure.
*
*/
int as_area_change_flags(as_t *as, int flags, uintptr_t address)
{
785,7 → 790,7
uintptr_t *old_frame;
index_t frame_idx;
count_t used_pages;
 
/* Flags for the new memory mapping */
page_flags = area_flags_to_page_flags(flags);
 
799,7 → 804,7
return ENOENT;
}
 
if (area->sh_info || area->backend != &anon_backend) {
if ((area->sh_info) || (area->backend != &anon_backend)) {
/* Copying shared areas not supported yet */
/* Copying non-anonymous memory not supported yet */
mutex_unlock(&area->lock);
870,6 → 875,7
*/
 
tlb_invalidate_pages(as->asid, area->base, area->pages);
/*
* Invalidate potential software translation caches (e.g. TSB on
* sparc64).
/branches/sparc/kernel/generic/src/syscall/syscall.c
92,8 → 92,12
/** Tell kernel to get keyboard/console access again */
static unative_t sys_debug_enable_console(void)
{
#ifdef CONFIG_KCONSOLE
arch_grab_console();
return 0;
return true;
#else
return false;
#endif
}
 
/** Dispatch system call */
/branches/sparc/kernel/generic/src/udebug/udebug.c
72,7 → 72,7
ut->uspace_state = NULL;
ut->go = false;
ut->stoppable = true;
ut->debug_active = false;
ut->active = false;
ut->cur_event = 0; /* none */
}
 
112,7 → 112,7
bool res;
 
mutex_lock(&THREAD->udebug.lock);
res = THREAD->udebug.debug_active;
res = THREAD->udebug.active;
mutex_unlock(&THREAD->udebug.lock);
 
return res;
170,7 → 170,7
* Active debugging session
*/
 
if (THREAD->udebug.debug_active == true &&
if (THREAD->udebug.active == true &&
THREAD->udebug.go == false) {
/*
* Thread was requested to stop - answer go call
210,8 → 210,7
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
if (THREAD->udebug.debug_active &&
THREAD->udebug.go == false) {
if (THREAD->udebug.active && THREAD->udebug.go == false) {
TASK->udebug.begin_call = NULL;
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
264,8 → 263,7
mutex_lock(&THREAD->udebug.lock);
 
/* Must only generate events when in debugging session and is go. */
if (THREAD->udebug.debug_active != true ||
THREAD->udebug.go == false ||
if (THREAD->udebug.active != true || THREAD->udebug.go == false ||
(TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) {
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
334,9 → 332,9
LOG("- check state\n");
 
/* Must only generate events when in debugging session */
if (THREAD->udebug.debug_active != true) {
LOG("- debug_active: %s, udebug.go: %s\n",
THREAD->udebug.debug_active ? "yes(+)" : "no(-)",
if (THREAD->udebug.active != true) {
LOG("- udebug.active: %s, udebug.go: %s\n",
THREAD->udebug.active ? "yes(+)" : "no(-)",
THREAD->udebug.go ? "yes(-)" : "no(+)");
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
384,9 → 382,9
LOG("- check state\n");
 
/* Must only generate events when in debugging session. */
if (THREAD->udebug.debug_active != true) {
/* printf("- debug_active: %s, udebug.go: %s\n",
THREAD->udebug.debug_active ? "yes(+)" : "no(-)",
if (THREAD->udebug.active != true) {
/* printf("- udebug.active: %s, udebug.go: %s\n",
THREAD->udebug.active ? "yes(+)" : "no(-)",
THREAD->udebug.go ? "yes(-)" : "no(+)");*/
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
401,7 → 399,7
IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E);
 
/* Prevent any further debug activity in thread. */
THREAD->udebug.debug_active = false;
THREAD->udebug.active = false;
THREAD->udebug.cur_event = 0; /* none */
THREAD->udebug.go = false; /* set to initial value */
 
459,13 → 457,13
/* Only process userspace threads. */
if ((flags & THREAD_FLAG_USPACE) != 0) {
/* Prevent any further debug activity in thread. */
t->udebug.debug_active = false;
t->udebug.active = false;
t->udebug.cur_event = 0; /* none */
 
/* Is the thread still go? */
if (t->udebug.go == true) {
/*
* Yes, so clear go. As debug_active == false,
* Yes, so clear go. As active == false,
* this doesn't affect anything.
*/
t->udebug.go = false;
/branches/sparc/kernel/generic/src/udebug/udebug_ops.c
58,7 → 58,7
* Specifically, verifies that thread t exists, is a userspace thread,
* and belongs to the current task (TASK). Verifies, that the thread
* is (or is not) go according to being_go (typically false).
* It also locks t->udebug.lock, making sure that t->udebug.debug_active
* It also locks t->udebug.lock, making sure that t->udebug.active
* is true - that the thread is in a valid debugging session.
*
* With this verified and the t->udebug.lock mutex held, it is ensured
108,7 → 108,7
}
 
/* Verify debugging state. */
if (t->udebug.debug_active != true) {
if (t->udebug.active != true) {
/* Not in debugging session or undesired GO state */
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
117,8 → 117,8
}
 
/*
* Since the thread has debug_active == true, TASK->udebug.lock
* is enough to ensure its existence and that debug_active remains
* Since the thread has active == true, TASK->udebug.lock
* is enough to ensure its existence and that active remains
* true.
*/
spinlock_unlock(&t->lock);
204,7 → 204,7
reply = 0; /* no reply */
}
/* Set udebug.debug_active on all of the task's userspace threads. */
/* Set udebug.active on all of the task's userspace threads. */
 
for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
t = list_get_instance(cur, thread_t, th_link);
211,7 → 211,7
 
mutex_lock(&t->udebug.lock);
if ((t->flags & THREAD_FLAG_USPACE) != 0)
t->udebug.debug_active = true;
t->udebug.active = true;
mutex_unlock(&t->udebug.lock);
}