/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); |
} |