/branches/dynload/kernel/genarch/src/fb/fb.c |
---|
184,11 → 184,12 |
/** Hide logo and refresh screen |
* |
*/ |
static void logo_hide(void) |
static void logo_hide(bool silent) |
{ |
ylogo = 0; |
ytrim = yres; |
rowtrim = rows; |
if (!silent) |
fb_redraw(); |
} |
196,7 → 197,7 |
/** Draw character at given position |
* |
*/ |
static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row) |
static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row, bool silent) |
{ |
unsigned int x = COL2X(col); |
unsigned int y = ROW2Y(row); |
203,14 → 204,16 |
unsigned int yd; |
if (y >= ytrim) |
logo_hide(); |
logo_hide(silent); |
backbuf[BB_POS(col, row)] = glyph; |
if (!silent) { |
for (yd = 0; yd < FONT_SCANLINES; yd++) |
memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)], |
&glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
} |
} |
/** Scroll screen down by one row |
217,13 → 220,14 |
* |
* |
*/ |
static void screen_scroll(void) |
static void screen_scroll(bool silent) |
{ |
if (ylogo > 0) { |
logo_hide(); |
logo_hide(silent); |
return; |
} |
if (!silent) { |
unsigned int row; |
for (row = 0; row < rows; row++) { |
253,6 → 257,7 |
} |
} |
} |
} |
memmove(backbuf, backbuf + cols, cols * (rows - 1)); |
memsetb(&backbuf[BB_POS(0, rows - 1)], cols, 0); |
259,15 → 264,15 |
} |
static void cursor_put(void) |
static void cursor_put(bool silent) |
{ |
glyph_draw(CURSOR, position % cols, position / cols); |
glyph_draw(CURSOR, position % cols, position / cols, silent); |
} |
static void cursor_remove(void) |
static void cursor_remove(bool silent) |
{ |
glyph_draw(0, position % cols, position / cols); |
glyph_draw(0, position % cols, position / cols, silent); |
} |
276,44 → 281,45 |
* Emulate basic terminal commands. |
* |
*/ |
static void fb_putchar(chardev_t *dev, char ch) |
static void fb_putchar(chardev_t *dev, char ch, bool silent) |
{ |
spinlock_lock(&fb_lock); |
switch (ch) { |
case '\n': |
cursor_remove(); |
cursor_remove(silent); |
position += cols; |
position -= position % cols; |
break; |
case '\r': |
cursor_remove(); |
cursor_remove(silent); |
position -= position % cols; |
break; |
case '\b': |
cursor_remove(); |
cursor_remove(silent); |
if (position % cols) |
position--; |
break; |
case '\t': |
cursor_remove(); |
cursor_remove(silent); |
do { |
glyph_draw((uint8_t) ' ', position % cols, |
position / cols); |
position / cols, silent); |
position++; |
} while ((position % 8) && (position < cols * rows)); |
break; |
default: |
glyph_draw((uint8_t) ch, position % cols, position / cols); |
glyph_draw((uint8_t) ch, position % cols, |
position / cols, silent); |
position++; |
} |
if (position >= cols * rows) { |
position -= cols; |
screen_scroll(); |
screen_scroll(silent); |
} |
cursor_put(); |
cursor_put(silent); |
spinlock_unlock(&fb_lock); |
} |
/branches/dynload/kernel/genarch/src/drivers/ega/ega.c |
---|
62,54 → 62,8 |
static uint8_t *backbuf; |
static ioport_t ega_base; |
static void ega_putchar(chardev_t *d, const char ch); |
chardev_t ega_console; |
static chardev_operations_t ega_ops = { |
.write = ega_putchar |
}; |
static void ega_move_cursor(void); |
void ega_init(ioport_t base, uintptr_t videoram_phys) |
{ |
/* Initialize the software structure. */ |
ega_base = base; |
backbuf = (uint8_t *) malloc(SCREEN * 2, 0); |
if (!backbuf) |
panic("Unable to allocate backbuffer."); |
videoram = (uint8_t *) hw_map(videoram_phys, SCREEN * 2); |
/* Clear the screen and set the cursor position. */ |
memsetw(videoram, SCREEN, 0x0720); |
memsetw(backbuf, SCREEN, 0x0720); |
ega_move_cursor(); |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
ega_parea.pbase = videoram_phys; |
ega_parea.vbase = (uintptr_t) videoram; |
ega_parea.frames = 1; |
ega_parea.cacheable = false; |
ddi_parea_register(&ega_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.blinking", NULL, true); |
sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys); |
} |
static void ega_display_char(char ch) |
{ |
videoram[ega_cursor * 2] = ch; |
backbuf[ega_cursor * 2] = ch; |
} |
/* |
* This function takes care of scrolling. |
*/ |
127,8 → 81,24 |
ega_cursor = ega_cursor - ROW; |
} |
void ega_putchar(chardev_t *d __attribute__((unused)), const char ch) |
static void ega_move_cursor(void) |
{ |
outb(ega_base + EGA_INDEX_REG, 0xe); |
outb(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff)); |
outb(ega_base + EGA_INDEX_REG, 0xf); |
outb(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff)); |
} |
static void ega_display_char(char ch, bool silent) |
{ |
backbuf[ega_cursor * 2] = ch; |
if (!silent) |
videoram[ega_cursor * 2] = ch; |
} |
static void ega_putchar(chardev_t *d __attribute__((unused)), const char ch, bool silent) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
146,11 → 116,13 |
ega_cursor--; |
break; |
default: |
ega_display_char(ch); |
ega_display_char(ch, silent); |
ega_cursor++; |
break; |
} |
ega_check_cursor(); |
if (!silent) |
ega_move_cursor(); |
spinlock_unlock(&egalock); |
157,12 → 129,41 |
interrupts_restore(ipl); |
} |
void ega_move_cursor(void) |
static chardev_operations_t ega_ops = { |
.write = ega_putchar |
}; |
void ega_init(ioport_t base, uintptr_t videoram_phys) |
{ |
outb(ega_base + EGA_INDEX_REG, 0xe); |
outb(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff)); |
outb(ega_base + EGA_INDEX_REG, 0xf); |
outb(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff)); |
/* Initialize the software structure. */ |
ega_base = base; |
backbuf = (uint8_t *) malloc(SCREEN * 2, 0); |
if (!backbuf) |
panic("Unable to allocate backbuffer."); |
videoram = (uint8_t *) hw_map(videoram_phys, SCREEN * 2); |
/* Clear the screen and set the cursor position. */ |
memsetw(videoram, SCREEN, 0x0720); |
memsetw(backbuf, SCREEN, 0x0720); |
ega_move_cursor(); |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
ega_parea.pbase = videoram_phys; |
ega_parea.vbase = (uintptr_t) videoram; |
ega_parea.frames = 1; |
ega_parea.cacheable = false; |
ddi_parea_register(&ega_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.blinking", NULL, true); |
sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys); |
} |
void ega_redraw(void) |
/branches/dynload/kernel/generic/include/interrupt.h |
---|
48,8 → 48,8 |
{ \ |
if (istate_from_uspace(istate)) { \ |
task_t *task = TASK; \ |
printf("Task %" PRIu64 " killed due to an exception at %p.", task->taskid, istate_get_pc(istate)); \ |
printf(" " fmt "\n", ##__VA_ARGS__); \ |
printf("Task %s (%" PRIu64 ") killed due to an exception at %p: ", task->name, task->taskid, istate_get_pc(istate)); \ |
printf(fmt "\n", ##__VA_ARGS__); \ |
task_kill(task->taskid); \ |
thread_exit(); \ |
} \ |
/branches/dynload/kernel/generic/include/console/chardev.h |
---|
50,7 → 50,7 |
/** Resume pushing characters. */ |
void (* resume)(struct chardev *); |
/** Write character to stream. */ |
void (* write)(struct chardev *, char c); |
void (* write)(struct chardev *, char c, bool silent); |
/** Read character directly from device, assume interrupts disabled. */ |
char (* read)(struct chardev *); |
} chardev_operations_t; |
/branches/dynload/kernel/generic/include/console/console.h |
---|
49,6 → 49,9 |
extern count_t gets(chardev_t *chardev, char *buf, size_t buflen); |
extern void putchar(char c); |
extern void grab_console(void); |
extern void release_console(void); |
extern void arch_grab_console(void); |
extern void arch_release_console(void); |
/branches/dynload/kernel/generic/include/macros.h |
---|
76,6 → 76,18 |
#define STRING(arg) STRING_ARG(arg) |
#define STRING_ARG(arg) #arg |
/** Pseudorandom generator |
* |
* A pretty standard linear congruential pseudorandom |
* number generator (m = 2^32 or 2^64 depending on architecture). |
* |
*/ |
#define RANDI(seed) \ |
({ \ |
(seed) = 1103515245 * (seed) + 12345; \ |
(seed); \ |
}) |
#endif |
/** @} |
/branches/dynload/kernel/generic/include/syscall/syscall.h |
---|
62,6 → 62,7 |
SYS_IPC_ANSWER_FAST, |
SYS_IPC_ANSWER_SLOW, |
SYS_IPC_FORWARD_FAST, |
SYS_IPC_FORWARD_SLOW, |
SYS_IPC_WAIT, |
SYS_IPC_HANGUP, |
SYS_IPC_REGISTER_IRQ, |
79,6 → 80,7 |
SYS_DEBUG_PUTINT, |
SYS_DEBUG_ENABLE_CONSOLE, |
SYS_DEBUG_DISABLE_CONSOLE, |
SYS_IPC_CONNECT_KBOX, |
SYSCALL_END |
} syscall_t; |
/branches/dynload/kernel/generic/include/ipc/sysipc.h |
---|
53,6 → 53,8 |
int nonblocking); |
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, |
unative_t method, unative_t arg1, unative_t arg2, int mode); |
unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid, |
ipc_data_t *data, int mode); |
unative_t sys_ipc_hangup(int phoneid); |
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method, |
irq_code_t *ucode); |
/branches/dynload/kernel/generic/src/main/kinit.c |
---|
72,6 → 72,10 |
#include <synch/waitq.h> |
#include <synch/spinlock.h> |
#define ALIVE_CHARS 4 |
static char alive[ALIVE_CHARS] = "-\\|/"; |
/** Kernel initialization thread. |
* |
* kinit takes care of higher level kernel |
204,11 → 208,12 |
#ifdef CONFIG_KCONSOLE |
if (!stdin) { |
printf("kinit: No stdin\nKernel alive: "); |
thread_sleep(10); |
printf("kinit: No stdin\nKernel alive: ."); |
uint64_t i = 0; |
while (1) { |
printf(PRIu64 " ", i); |
unsigned int i = 0; |
while (true) { |
printf("\b%c", alive[i % ALIVE_CHARS]); |
thread_sleep(1); |
i++; |
} |
/branches/dynload/kernel/generic/src/console/console.c |
---|
65,6 → 65,9 |
/**< Number of stored kernel log characters for uspace */ |
static size_t klog_uspace = 0; |
/**< Silent output */ |
static bool silent = false; |
/**< Kernel log spinlock */ |
SPINLOCK_INITIALIZE(klog_lock); |
144,6 → 147,18 |
spinlock_unlock(&klog_lock); |
} |
void grab_console(void) |
{ |
silent = false; |
arch_grab_console(); |
} |
void release_console(void) |
{ |
silent = true; |
arch_release_console(); |
} |
/** Get character from character device. Do not echo character. |
* |
* @param chardev Character device. |
253,7 → 268,7 |
/* Print charaters stored in kernel log */ |
index_t i; |
for (i = klog_len - klog_stored; i < klog_len; i++) |
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE]); |
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE], silent); |
klog_stored = 0; |
} |
265,7 → 280,7 |
klog_start = (klog_start + 1) % KLOG_SIZE; |
if (stdout->op->write) |
stdout->op->write(stdout, c); |
stdout->op->write(stdout, c, silent); |
else { |
/* The character is just in the kernel log */ |
if (klog_stored < klog_len) |
/branches/dynload/kernel/generic/src/console/cmd.c |
---|
976,7 → 976,7 |
int cmd_continue(cmd_arg_t *argv) |
{ |
printf("The kernel will now relinquish the console.\n"); |
arch_release_console(); |
release_console(); |
if ((kconsole_notify) && (kconsole_irq.notif_cfg.notify)) |
ipc_irq_send_msg_0(&kconsole_irq); |
/branches/dynload/kernel/generic/src/printf/vprintf.c |
---|
62,13 → 62,13 |
{ |
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vprintf_write, NULL}; |
int irqpri = interrupts_disable(); |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&printf_lock); |
int ret = printf_core(fmt, &ps, ap); |
spinlock_unlock(&printf_lock); |
interrupts_restore(irqpri); |
interrupts_restore(ipl); |
return ret; |
} |
/branches/dynload/kernel/generic/src/syscall/syscall.c |
---|
62,7 → 62,6 |
*/ |
static unative_t sys_klog(int fd, const void * buf, size_t count) |
{ |
size_t i; |
char *data; |
int rc; |
70,7 → 69,7 |
return ELIMIT; |
if (count > 0) { |
data = (char *) malloc(count, 0); |
data = (char *) malloc(count + 1, 0); |
if (!data) |
return ENOMEM; |
79,9 → 78,9 |
free(data); |
return rc; |
} |
data[count] = 0; |
for (i = 0; i < count; i++) |
putchar(data[i]); |
printf("%s", data); |
free(data); |
} else |
klog_update(); |
93,7 → 92,7 |
static unative_t sys_debug_enable_console(void) |
{ |
#ifdef CONFIG_KCONSOLE |
arch_grab_console(); |
grab_console(); |
return true; |
#else |
return false; |
107,6 → 106,13 |
return 0; |
} |
/** Tell kernel to relinquish keyboard/console access */ |
static unative_t sys_debug_disable_console(void) |
{ |
release_console(); |
return true; |
} |
/** Dispatch system call */ |
unative_t syscall_handler(unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5, unative_t a6, unative_t id) |
171,6 → 177,7 |
(syshandler_t) sys_ipc_answer_fast, |
(syshandler_t) sys_ipc_answer_slow, |
(syshandler_t) sys_ipc_forward_fast, |
(syshandler_t) sys_ipc_forward_slow, |
(syshandler_t) sys_ipc_wait_for_call, |
(syshandler_t) sys_ipc_hangup, |
(syshandler_t) sys_ipc_register_irq, |
192,6 → 199,7 |
/* Debug calls */ |
(syshandler_t) sys_debug_putint, |
(syshandler_t) sys_debug_enable_console, |
(syshandler_t) sys_debug_disable_console, |
(syshandler_t) sys_ipc_connect_kbox |
}; |
/branches/dynload/kernel/generic/src/ipc/sysipc.c |
---|
618,7 → 618,8 |
return (unative_t) call; |
} |
/** Forward a received call to another destination. |
/** Forward a received call to another destination - common code for both the |
* fast and the slow version. |
* |
* @param callid Hash of the call to forward. |
* @param phoneid Phone handle to use for forwarding. |
625,23 → 626,21 |
* @param method New method to use for the forwarded call. |
* @param arg1 New value of the first argument for the forwarded call. |
* @param arg2 New value of the second argument for the forwarded call. |
* @param arg3 New value of the third argument for the forwarded call. |
* @param arg4 New value of the fourth argument for the forwarded call. |
* @param arg5 New value of the fifth argument for the forwarded call. |
* @param mode Flags that specify mode of the forward operation. |
* @param slow If true, arg3, arg4 and arg5 are considered. Otherwise |
* the function considers only the fast version arguments: |
* i.e. arg1 and arg2. |
* |
* @return Return 0 on succes, otherwise return an error code. |
* |
* In case the original method is a system method, ARG1, ARG2 and ARG3 are |
* overwritten in the forwarded message with the new method and the new arg1 and |
* arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are rewritten with |
* the new method, arg1 and arg2, respectively. Also note there is a set of |
* immutable methods, for which the new method and argument is not set and |
* these values are ignored. |
* |
* Warning: When implementing support for changing additional payload |
* arguments, make sure that ARG5 is not rewritten for certain |
* system IPC |
* Warning: Make sure that ARG5 is not rewritten for certain system IPC |
*/ |
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, |
unative_t method, unative_t arg1, unative_t arg2, int mode) |
static unative_t sys_ipc_forward_common(unative_t callid, unative_t phoneid, |
unative_t method, unative_t arg1, unative_t arg2, unative_t arg3, |
unative_t arg4, unative_t arg5, int mode, bool slow) |
{ |
call_t *call; |
phone_t *phone; |
666,8 → 665,8 |
/* |
* Userspace is not allowed to change method of system methods on |
* forward, allow changing ARG1, ARG2 and ARG3 by means of method, |
* arg1 and arg2. |
* forward, allow changing ARG1, ARG2, ARG3 and ARG4 by means of method, |
* arg1, arg2 and arg3. |
* If the method is immutable, don't change anything. |
*/ |
if (!method_is_immutable(IPC_GET_METHOD(call->data))) { |
678,16 → 677,86 |
IPC_SET_ARG1(call->data, method); |
IPC_SET_ARG2(call->data, arg1); |
IPC_SET_ARG3(call->data, arg2); |
if (slow) { |
IPC_SET_ARG4(call->data, arg3); |
/* |
* For system methods we deliberately don't |
* overwrite ARG5. |
*/ |
} |
} else { |
IPC_SET_METHOD(call->data, method); |
IPC_SET_ARG1(call->data, arg1); |
IPC_SET_ARG2(call->data, arg2); |
if (slow) { |
IPC_SET_ARG3(call->data, arg3); |
IPC_SET_ARG4(call->data, arg4); |
IPC_SET_ARG5(call->data, arg5); |
} |
} |
} |
return ipc_forward(call, phone, &TASK->answerbox, mode); |
} |
/** Forward a received call to another destination - fast version. |
* |
* @param callid Hash of the call to forward. |
* @param phoneid Phone handle to use for forwarding. |
* @param method New method to use for the forwarded call. |
* @param arg1 New value of the first argument for the forwarded call. |
* @param arg2 New value of the second argument for the forwarded call. |
* @param mode Flags that specify mode of the forward operation. |
* |
* @return Return 0 on succes, otherwise return an error code. |
* |
* In case the original method is a system method, ARG1, ARG2 and ARG3 are |
* overwritten in the forwarded message with the new method and the new |
* arg1 and arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are |
* rewritten with the new method, arg1 and arg2, respectively. Also note there |
* is a set of immutable methods, for which the new method and arguments are not |
* set and these values are ignored. |
*/ |
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, |
unative_t method, unative_t arg1, unative_t arg2, int mode) |
{ |
return sys_ipc_forward_common(callid, phoneid, method, arg1, arg2, 0, 0, |
0, mode, false); |
} |
/** Forward a received call to another destination - slow version. |
* |
* @param callid Hash of the call to forward. |
* @param phoneid Phone handle to use for forwarding. |
* @param data Userspace address of the new IPC data. |
* @param mode Flags that specify mode of the forward operation. |
* |
* @return Return 0 on succes, otherwise return an error code. |
* |
* This function is the slow verision of the sys_ipc_forward_fast interface. |
* It can copy all five new arguments and the new method from the userspace. |
* It naturally extends the functionality of the fast version. For system |
* methods, it additionally stores the new value of arg3 to ARG4. For non-system |
* methods, it additionally stores the new value of arg3, arg4 and arg5, |
* respectively, to ARG3, ARG4 and ARG5, respectively. |
*/ |
unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid, |
ipc_data_t *data, int mode) |
{ |
ipc_data_t newdata; |
int rc; |
rc = copy_from_uspace(&newdata.args, &data->args, |
sizeof(newdata.args)); |
if (rc != 0) |
return (unative_t) rc; |
return sys_ipc_forward_common(callid, phoneid, |
IPC_GET_METHOD(newdata), IPC_GET_ARG1(newdata), |
IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata), |
IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true); |
} |
/** Answer an IPC call - fast version. |
* |
* This function can handle only two return arguments of payload, but is faster |
/branches/dynload/kernel/arch/sparc64/src/drivers/sgcn.c |
---|
146,7 → 146,7 |
/* functions referenced from definitions of I/O operations structures */ |
static void sgcn_noop(chardev_t *); |
static void sgcn_putchar(chardev_t *, const char); |
static void sgcn_putchar(chardev_t *, const char, bool); |
static char sgcn_key_read(chardev_t *); |
/** character device operations */ |
295,17 → 295,18 |
* feed character is written ('\n'), the carriage return character ('\r') is |
* written straight away. |
*/ |
static void sgcn_putchar(struct chardev * cd, const char c) |
static void sgcn_putchar(struct chardev * cd, const char c, bool silent) |
{ |
if (!silent) { |
spinlock_lock(&sgcn_output_lock); |
sgcn_do_putchar(c); |
if (c == '\n') { |
if (c == '\n') |
sgcn_do_putchar('\r'); |
} |
spinlock_unlock(&sgcn_output_lock); |
} |
} |
/** |
* Called when actively reading the character. Not implemented yet. |
/branches/dynload/kernel/arch/ia64/src/ski/ski.c |
---|
56,9 → 56,6 |
static bool kbd_disabled; |
static void ski_putchar(chardev_t *d, const char ch); |
static int32_t ski_getchar(void); |
/** Display character on debug console |
* |
* Use SSC (Simulator System Call) to |
67,8 → 64,9 |
* @param d Character device. |
* @param ch Character to be printed. |
*/ |
void ski_putchar(chardev_t *d, const char ch) |
static void ski_putchar(chardev_t *d, const char ch, bool silent) |
{ |
if (!silent) { |
asm volatile ( |
"mov r15 = %0\n" |
"mov r32 = %1\n" /* r32 is in0 */ |
79,8 → 77,9 |
); |
if (ch == '\n') |
ski_putchar(d, '\r'); |
ski_putchar(d, '\r', false); |
} |
} |
/** Ask debug console if a key was pressed. |
* |
91,7 → 90,7 |
* |
* @return ASCII code of pressed key or 0 if no key pressed. |
*/ |
int32_t ski_getchar(void) |
static int32_t ski_getchar(void) |
{ |
uint64_t ch; |
/branches/dynload/kernel/arch/arm32/include/machine.h |
---|
111,8 → 111,7 |
#define machine_cpu_halt gxemul_cpu_halt |
#define machine_get_memory_size gxemul_get_memory_size |
#define machine_debug_putc(ch) gxemul_debug_putc(ch) |
#define machine_irq_exception(exc_no, istate) \ |
gxemul_irq_exception(exc_no, istate) |
#define machine_irq_exception(exc_no, istate) gxemul_irq_exception(exc_no, istate) |
#define machine_get_fb_address gxemul_get_fb_address |
#endif |
/branches/dynload/kernel/arch/arm32/src/drivers/gxemul.c |
---|
133,8 → 133,9 |
* @param dev Not used. |
* @param ch Characted to be printed. |
*/ |
static void gxemul_write(chardev_t *dev, const char ch) |
static void gxemul_write(chardev_t *dev, const char ch, bool silent) |
{ |
if (!silent) |
*((char *) gxemul_hw_map.videoram) = ch; |
} |
/branches/dynload/kernel/arch/ppc32/include/asm/regname.h |
---|
211,6 → 211,9 |
#define dbat2l 541 |
#define dbat3u 542 |
#define dbat3l 543 |
#define tlbmiss 980 |
#define ptehi 981 |
#define ptelo 982 |
#define hid0 1008 |
/* MSR bits */ |
220,6 → 223,7 |
#define msr_ee (1 << 15) |
/* HID0 bits */ |
#define hid0_sten (1 << 24) |
#define hid0_ice (1 << 15) |
#define hid0_dce (1 << 14) |
#define hid0_icfi (1 << 11) |
/branches/dynload/kernel/arch/ppc32/include/exception.h |
---|
75,6 → 75,7 |
uint32_t lr; |
uint32_t ctr; |
uint32_t xer; |
uint32_t dar; |
uint32_t r12; |
uint32_t sp; |
} istate_t; |
/branches/dynload/kernel/arch/ppc32/include/types.h |
---|
84,9 → 84,11 |
/** Page Table Entry. */ |
typedef struct { |
unsigned p : 1; /**< Present bit. */ |
unsigned a : 1; /**< Accessed bit. */ |
unsigned g : 1; /**< Global bit. */ |
unsigned present : 1; /**< Present bit. */ |
unsigned page_write_through : 1; /**< Write thought caching. */ |
unsigned page_cache_disable : 1; /**< No caching. */ |
unsigned accessed : 1; /**< Accessed bit. */ |
unsigned global : 1; /**< Global bit. */ |
unsigned valid : 1; /**< Valid content even if not present. */ |
unsigned pfn : 20; /**< Physical frame number. */ |
} pte_t; |
/branches/dynload/kernel/arch/ppc32/include/boot/boot.h |
---|
79,13 → 79,13 |
typedef struct { |
uintptr_t addr; |
unsigned int size; |
} keyboard_t; |
} macio_t; |
typedef struct { |
memmap_t memmap; |
taskmap_t taskmap; |
screen_t screen; |
keyboard_t keyboard; |
macio_t macio; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
/branches/dynload/kernel/arch/ppc32/include/mm/page.h |
---|
120,7 → 120,7 |
/* Macros for querying the last-level PTEs. */ |
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->present != 0) |
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12) |
#define PTE_WRITABLE_ARCH(pte) 1 |
#define PTE_EXECUTABLE_ARCH(pte) 1 |
134,13 → 134,13 |
{ |
pte_t *p = &pt[i]; |
return ((1 << PAGE_CACHEABLE_SHIFT) | |
((!p->p) << PAGE_PRESENT_SHIFT) | |
return (((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT) | |
((!p->present) << PAGE_PRESENT_SHIFT) | |
(1 << PAGE_USER_SHIFT) | |
(1 << PAGE_READ_SHIFT) | |
(1 << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | |
(p->g << PAGE_GLOBAL_SHIFT)); |
(p->global << PAGE_GLOBAL_SHIFT)); |
} |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
147,8 → 147,9 |
{ |
pte_t *p = &pt[i]; |
p->p = !(flags & PAGE_NOT_PRESENT); |
p->g = (flags & PAGE_GLOBAL) != 0; |
p->page_cache_disable = !(flags & PAGE_CACHEABLE); |
p->present = !(flags & PAGE_NOT_PRESENT); |
p->global = (flags & PAGE_GLOBAL) != 0; |
p->valid = 1; |
} |
/branches/dynload/kernel/arch/ppc32/include/mm/tlb.h |
---|
39,6 → 39,11 |
#include <arch/types.h> |
#include <typedefs.h> |
#define WIMG_GUARDED 0x01 |
#define WIMG_COHERENT 0x02 |
#define WIMG_NO_CACHE 0x04 |
#define WIMG_WRITETHRU 0x08 |
typedef struct { |
unsigned v : 1; /**< Valid */ |
unsigned vsid : 24; /**< Virtual Segment ID */ |
53,9 → 58,27 |
unsigned pp : 2; /**< Page protection */ |
} phte_t; |
typedef struct { |
unsigned v : 1; |
unsigned vsid : 24; |
unsigned reserved0 : 1; |
unsigned api : 6; |
} ptehi_t; |
typedef struct { |
unsigned rpn : 20; |
unsigned xpn : 3; |
unsigned reserved0 : 1; |
unsigned c : 1; |
unsigned wimg : 4; |
unsigned x : 1; |
unsigned pp : 2; |
} ptelo_t; |
extern void pht_init(void); |
extern void pht_refill(int n, istate_t *istate); |
extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
extern void pht_init(void); |
extern bool pht_refill_real(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
extern void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
#endif |
/branches/dynload/kernel/arch/ppc32/include/barrier.h |
---|
55,6 → 55,7 |
"dcbst 0, %0\n" |
"sync\n" |
"icbi 0, %0\n" |
"sync\n" |
"isync\n" |
:: "r" (addr) |
); |
76,7 → 77,10 |
asm volatile ("icbi 0, %0\n" :: "r" (addr + i)); |
} |
asm volatile ("isync"); |
asm volatile ( |
"sync\n" |
"isync\n" |
); |
} |
#endif |
/branches/dynload/kernel/arch/ppc32/src/exception.S |
---|
60,7 → 60,7 |
2: |
subi sp, sp, 160 |
subi sp, sp, 164 |
stw r0, 8(sp) |
stw r2, 12(sp) |
stw r3, 16(sp) |
109,11 → 109,14 |
mfxer r12 |
stw r12, 148(sp) |
mfsprg1 r12 |
mfdar r12 |
stw r12, 152(sp) |
mfsprg1 r12 |
stw r12, 156(sp) |
mfsprg2 r12 |
stw r12, 156(sp) |
stw r12, 160(sp) |
.endm |
.org 0x100 |
137,33 → 140,15 |
exc_data_storage: |
CONTEXT_STORE |
li r3, 2 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_real_refill |
b data_storage |
cmpwi r3, 0 |
bne iret_real |
li r3, 2 |
b jump_to_kernel |
.org 0x400 |
.global exc_instruction_storage |
exc_instruction_storage: |
CONTEXT_STORE |
li r3, 3 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_real_refill |
b instruction_storage |
cmpwi r3, 0 |
bne iret_real |
li r3, 3 |
b jump_to_kernel |
.org 0x500 |
.global exc_external |
exc_external: |
235,7 → 220,63 |
li r3, 12 |
b jump_to_kernel |
.org 0x1000 |
.global exc_itlb_miss |
exc_itlb_miss: |
CONTEXT_STORE |
b tlb_miss |
.org 0x1100 |
.global exc_dtlb_miss_load |
exc_dtlb_miss_load: |
CONTEXT_STORE |
b tlb_miss |
.org 0x1200 |
.global exc_dtlb_miss_store |
exc_dtlb_miss_store: |
CONTEXT_STORE |
b tlb_miss |
.org 0x4000 |
data_storage: |
li r3, 2 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_refill_real |
cmpwi r3, 0 |
bne iret_real |
li r3, 2 |
b jump_to_kernel |
instruction_storage: |
li r3, 3 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_refill_real |
cmpwi r3, 0 |
bne iret_real |
li r3, 3 |
b jump_to_kernel |
tlb_miss: |
li r3, 16 |
mfspr r4, tlbmiss |
mfspr r5, ptehi |
mfspr r6, ptelo |
mr r7, sp |
addi r7, r7, 20 |
bl tlb_refill_real |
b iret_real |
jump_to_kernel: |
lis r12, iret@ha |
addi r12, r12, iret@l |
272,7 → 313,6 |
rfi |
iret_real: |
lwz r0, 8(sp) |
lwz r2, 12(sp) |
lwz r3, 16(sp) |
322,7 → 362,7 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
rfi |
/branches/dynload/kernel/arch/ppc32/src/asm.S |
---|
131,8 → 131,8 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
rfi |
197,8 → 197,8 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
rfi |
/branches/dynload/kernel/arch/ppc32/src/ppc32.c |
---|
76,6 → 76,7 |
{ |
if (config.cpu_active == 1) { |
/* Initialize framebuffer */ |
if (bootinfo.screen.addr) { |
unsigned int visual; |
switch (bootinfo.screen.bpp) { |
103,16 → 104,19 |
.visual = visual, |
}; |
fb_init(&prop); |
} |
/* Initialize IRQ routing */ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
if (bootinfo.macio.addr) { |
/* Initialize PIC */ |
pic_init(bootinfo.keyboard.addr, PAGE_SIZE); |
pic_init(bootinfo.macio.addr, PAGE_SIZE); |
/* Initialize I/O controller */ |
cuda_init(device_assign_devno(), |
bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE); |
bootinfo.macio.addr + 0x16000, 2 * PAGE_SIZE); |
} |
/* Merge all zones to 1 big zone */ |
zone_merge_all(); |
143,8 → 147,7 |
(uintptr_t) kernel_uarg->uspace_entry); |
/* Unreachable */ |
for (;;) |
; |
while (true); |
} |
/** Acquire console back for kernel |
/branches/dynload/kernel/arch/ppc32/src/mm/tlb.c |
---|
40,8 → 40,18 |
#include <arch.h> |
#include <print.h> |
#include <symtab.h> |
#include <macros.h> |
static unsigned int seed = 10; |
static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42; |
#define TLB_FLUSH \ |
"tlbie %0\n" \ |
"addi %0, %0, 0x1000\n" |
/** Try to find PTE for faulting address |
* |
* Try to find PTE for faulting address. |
66,7 → 76,7 |
* Check if the mapping exists in page tables. |
*/ |
pte_t *pte = page_mapping_find(as, badvaddr); |
if ((pte) && (pte->p)) { |
if ((pte) && (pte->present)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
88,7 → 98,7 |
*/ |
page_table_lock(as, lock); |
pte = page_mapping_find(as, badvaddr); |
ASSERT((pte) && (pte->p)); |
ASSERT((pte) && (pte->present)); |
*pfrc = 0; |
return pte; |
case AS_PF_DEFER: |
111,22 → 121,21 |
char *symbol = ""; |
char *sym2 = ""; |
char *s = get_symtab_entry(istate->pc); |
if (s) |
symbol = s; |
s = get_symtab_entry(istate->lr); |
if (s) |
sym2 = s; |
char *str = get_symtab_entry(istate->pc); |
if (str) |
symbol = str; |
str = get_symtab_entry(istate->lr); |
if (str) |
sym2 = str; |
fault_if_from_uspace(istate, |
"%p: PHT Refill Exception at %p (%s<-%s).", badvaddr, |
istate->pc, symbol, sym2); |
"PHT Refill Exception on %p.", badvaddr); |
panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr, |
istate->pc, symbol, sym2); |
} |
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn) |
static void pht_insert(const uintptr_t vaddr, const pte_t *pte) |
{ |
uint32_t page = (vaddr >> 12) & 0xffff; |
uint32_t api = (vaddr >> 22) & 0x3f; |
152,11 → 161,12 |
uint32_t i; |
bool found = false; |
/* Find unused or colliding |
PTE in PTEG */ |
/* Find colliding PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && |
(phte[base + i].api == api))) { |
if ((phte[base + i].v) |
&& (phte[base + i].vsid == vsid) |
&& (phte[base + i].api == api) |
&& (phte[base + i].h == 0)) { |
found = true; |
break; |
} |
163,86 → 173,36 |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find unused or colliding |
PTE in PTEG */ |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte[base2 + i].v) || |
((phte[base2 + i].vsid == vsid) && |
(phte[base2 + i].api == api))) { |
if (!phte[base + i].v) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
} |
if (!found) { |
// TODO: A/C precedence groups |
i = page % 8; |
} |
} |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
phte[base + i].v = 1; |
phte[base + i].vsid = vsid; |
phte[base + i].h = h; |
phte[base + i].api = api; |
phte[base + i].rpn = pfn; |
phte[base + i].r = 0; |
phte[base + i].c = 0; |
phte[base + i].pp = 2; // FIXME |
} |
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn) |
{ |
uint32_t page = (vaddr >> 12) & 0xffff; |
uint32_t api = (vaddr >> 22) & 0x3f; |
uint32_t vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (vaddr) |
); |
uint32_t sdr1; |
asm volatile ( |
"mfsdr1 %0\n" |
: "=r" (sdr1) |
); |
phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000); |
/* Primary hash (xor) */ |
uint32_t h = 0; |
uint32_t hash = vsid ^ page; |
uint32_t base = (hash & 0x3ff) << 3; |
uint32_t i; |
bool found = false; |
/* Find unused or colliding |
PTE in PTEG */ |
/* Find colliding PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte_physical[base + i].v) || |
((phte_physical[base + i].vsid == vsid) && |
(phte_physical[base + i].api == api))) { |
if ((phte[base2 + i].v) |
&& (phte[base2 + i].vsid == vsid) |
&& (phte[base2 + i].api == api) |
&& (phte[base2 + i].h == 1)) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find unused or colliding |
PTE in PTEG */ |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte_physical[base2 + i].v) || |
((phte_physical[base2 + i].vsid == vsid) && |
(phte_physical[base2 + i].api == api))) { |
if (!phte[base2 + i].v) { |
found = true; |
base = base2; |
h = 1; |
249,27 → 209,27 |
break; |
} |
} |
} |
if (!found) { |
// TODO: A/C precedence groups |
i = page % 8; |
if (!found) |
i = RANDI(seed) % 8; |
} |
} |
phte_physical[base + i].v = 1; |
phte_physical[base + i].vsid = vsid; |
phte_physical[base + i].h = h; |
phte_physical[base + i].api = api; |
phte_physical[base + i].rpn = pfn; |
phte_physical[base + i].r = 0; |
phte_physical[base + i].c = 0; |
phte_physical[base + i].pp = 2; // FIXME |
phte[base + i].v = 1; |
phte[base + i].vsid = vsid; |
phte[base + i].h = h; |
phte[base + i].api = api; |
phte[base + i].rpn = pte->pfn; |
phte[base + i].r = 0; |
phte[base + i].c = 0; |
phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0); |
phte[base + i].pp = 2; // FIXME |
} |
/** Process Instruction/Data Storage Interrupt |
/** Process Instruction/Data Storage Exception |
* |
* @param n Interrupt vector number. |
* @param n Exception vector number. |
* @param istate Interrupted register context. |
* |
*/ |
289,12 → 249,9 |
lock = true; |
} |
if (n == VECTOR_DATA_STORAGE) { |
asm volatile ( |
"mfdar %0\n" |
: "=r" (badvaddr) |
); |
} else |
if (n == VECTOR_DATA_STORAGE) |
badvaddr = istate->dar; |
else |
badvaddr = istate->pc; |
page_table_lock(as, lock); |
318,8 → 275,8 |
} |
} |
pte->a = 1; /* Record access to PTE */ |
pht_insert(badvaddr, pte->pfn); |
pte->accessed = 1; /* Record access to PTE */ |
pht_insert(badvaddr, pte); |
page_table_unlock(as, lock); |
return; |
330,22 → 287,19 |
} |
/** Process Instruction/Data Storage Interrupt in Real Mode |
/** Process Instruction/Data Storage Exception in Real Mode |
* |
* @param n Interrupt vector number. |
* @param n Exception vector number. |
* @param istate Interrupted register context. |
* |
*/ |
bool pht_real_refill(int n, istate_t *istate) |
bool pht_refill_real(int n, istate_t *istate) |
{ |
uintptr_t badvaddr; |
if (n == VECTOR_DATA_STORAGE) { |
asm volatile ( |
"mfdar %0\n" |
: "=r" (badvaddr) |
); |
} else |
if (n == VECTOR_DATA_STORAGE) |
badvaddr = istate->dar; |
else |
badvaddr = istate->pc; |
uint32_t physmem; |
354,12 → 308,137 |
: "=r" (physmem) |
); |
if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) { |
pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12); |
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) |
return false; |
uint32_t page = (badvaddr >> 12) & 0xffff; |
uint32_t api = (badvaddr >> 22) & 0x3f; |
uint32_t vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (badvaddr) |
); |
uint32_t sdr1; |
asm volatile ( |
"mfsdr1 %0\n" |
: "=r" (sdr1) |
); |
phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); |
/* Primary hash (xor) */ |
uint32_t h = 0; |
uint32_t hash = vsid ^ page; |
uint32_t base = (hash & 0x3ff) << 3; |
uint32_t i; |
bool found = false; |
/* Find colliding PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte_real[base + i].v) |
&& (phte_real[base + i].vsid == vsid) |
&& (phte_real[base + i].api == api) |
&& (phte_real[base + i].h == 0)) { |
found = true; |
break; |
} |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte_real[base + i].v) { |
found = true; |
break; |
} |
} |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find colliding PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte_real[base2 + i].v) |
&& (phte_real[base2 + i].vsid == vsid) |
&& (phte_real[base2 + i].api == api) |
&& (phte_real[base2 + i].h == 1)) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte_real[base2 + i].v) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
} |
if (!found) { |
/* Use secondary hash to avoid collisions |
with usual PHT refill handler. */ |
i = RANDI(seed_real) % 8; |
base = base2; |
h = 1; |
} |
} |
phte_real[base + i].v = 1; |
phte_real[base + i].vsid = vsid; |
phte_real[base + i].h = h; |
phte_real[base + i].api = api; |
phte_real[base + i].rpn = KA2PA(badvaddr) >> 12; |
phte_real[base + i].r = 0; |
phte_real[base + i].c = 0; |
phte_real[base + i].wimg = 0; |
phte_real[base + i].pp = 2; // FIXME |
return true; |
} |
return false; |
/** Process ITLB/DTLB Miss Exception in Real Mode |
* |
* |
*/ |
void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) |
{ |
uint32_t badvaddr = tlbmiss & 0xfffffffc; |
uint32_t physmem; |
asm volatile ( |
"mfsprg3 %0\n" |
: "=r" (physmem) |
); |
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) |
return; // FIXME |
ptelo.rpn = KA2PA(badvaddr) >> 12; |
ptelo.wimg = 0; |
ptelo.pp = 2; // FIXME |
uint32_t index = 0; |
asm volatile ( |
"mtspr 981, %0\n" |
"mtspr 982, %1\n" |
"tlbld %2\n" |
"tlbli %2\n" |
: "=r" (index) |
: "r" (ptehi), |
"r" (ptelo) |
); |
} |
371,9 → 450,87 |
void tlb_invalidate_all(void) |
{ |
uint32_t index; |
asm volatile ( |
"tlbia\n" |
"li %0, 0\n" |
"sync\n" |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
"eieio\n" |
"tlbsync\n" |
"sync\n" |
: "=r" (index) |
); |
} |
442,7 → 599,7 |
: "=r" (vsid) |
: "r" (sr << 28) |
); |
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, |
printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr, |
sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, |
((vsid >> 30) & 1) ? " supervisor" : "", |
((vsid >> 29) & 1) ? " user" : ""); |
/branches/dynload/kernel/arch/ppc32/src/interrupt.c |
---|
92,8 → 92,8 |
static void exception_decrementer(int n, istate_t *istate) |
{ |
start_decrementer(); |
clock(); |
start_decrementer(); |
} |
/branches/dynload/kernel/arch/ppc32/src/drivers/pic.c |
---|
38,7 → 38,7 |
#include <byteorder.h> |
#include <bitops.h> |
static volatile uint32_t *pic; |
static volatile uint32_t *pic = NULL; |
void pic_init(uintptr_t base, size_t size) |
{ |
47,9 → 47,10 |
void pic_enable_interrupt(int intnum) |
{ |
if (intnum < 32) { |
if (pic) { |
if (intnum < 32) |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum); |
} else { |
else |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32)); |
} |
57,9 → 58,10 |
void pic_disable_interrupt(int intnum) |
{ |
if (intnum < 32) { |
if (pic) { |
if (intnum < 32) |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum)); |
} else { |
else |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32))); |
} |
} |
66,15 → 68,18 |
void pic_ack_interrupt(int intnum) |
{ |
if (pic) { |
if (intnum < 32) |
pic[PIC_ACK_LOW] = 1 << intnum; |
else |
pic[PIC_ACK_HIGH] = 1 << (intnum - 32); |
} |
} |
/** Return number of pending interrupt */ |
int pic_get_pending(void) |
{ |
if (pic) { |
int pending; |
pending = pic[PIC_PENDING_LOW]; |
84,6 → 89,7 |
pending = pic[PIC_PENDING_HIGH]; |
if (pending) |
return fnzb32(pending) + 32; |
} |
return -1; |
} |
/branches/dynload/kernel/arch/ppc32/src/drivers/cuda.c |
---|
236,6 → 236,7 |
int cuda_get_scancode(void) |
{ |
if (cuda) { |
uint8_t kind; |
uint8_t data[4]; |
243,6 → 244,7 |
if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c)) |
return data[2]; |
} |
return -1; |
} |
271,6 → 273,7 |
/** Initialize keyboard and service interrupts using kernel routine */ |
void cuda_grab(void) |
{ |
if (cuda) { |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&cuda_irq.lock); |
cuda_irq.notif_cfg.notify = false; |
277,11 → 280,13 |
spinlock_unlock(&cuda_irq.lock); |
interrupts_restore(ipl); |
} |
} |
/** Resume the former interrupt vector */ |
void cuda_release(void) |
{ |
if (cuda) { |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&cuda_irq.lock); |
if (cuda_irq.notif_cfg.answerbox) |
289,6 → 294,7 |
spinlock_unlock(&cuda_irq.unlock); |
interrupts_restore(ipl); |
} |
} |
void cuda_init(devno_t devno, uintptr_t base, size_t size) |
345,7 → 351,9 |
} |
void arch_reboot(void) { |
if (cuda) |
send_packet(PACKET_CUDA, 1, CUDA_RESET); |
asm volatile ( |
"b 0\n" |
); |
/branches/dynload/kernel/arch/ia32xen/src/drivers/xconsole.c |
---|
55,8 → 55,9 |
stdout = &xen_console; |
} |
void xen_putchar(chardev_t *d, const char ch) |
void xen_putchar(chardev_t *d, const char ch, bool silent) |
{ |
if (!silent) { |
if (start_info.console.domU.evtchn != 0) { |
uint32_t cons = console_page.out_cons; |
uint32_t prod = console_page.out_prod; |
78,6 → 79,7 |
} else |
xen_console_io(CONSOLE_IO_WRITE, 1, &ch); |
} |
} |
/** @} |
*/ |
/branches/dynload/kernel/arch/amd64/src/boot/boot.S |
---|
1,4 → 1,4 |
# |
# Copyright (c) 2005 Ondrej Palkovsky |
# Copyright (c) 2006 Martin Decky |
# Copyright (c) 2008 Jakub Jermar |
/branches/dynload/kernel/arch/amd64/src/interrupt.c |
---|
150,11 → 150,13 |
#endif |
} |
#ifdef CONFIG_SMP |
static void tlb_shootdown_ipi(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |
tlb_shootdown_ipi_recv(); |
} |
#endif |
/** Handler of IRQ exceptions */ |
static void irq_interrupt(int n, istate_t *istate) |
/branches/dynload/kernel/arch/ppc64/src/mm/tlb.c |
---|
49,7 → 49,6 |
void tlb_invalidate_all(void) |
{ |
asm volatile ( |
"tlbia\n" |
"tlbsync\n" |
); |
} |
/branches/dynload/kernel/arch/mips32/src/drivers/serial.c |
---|
46,17 → 46,19 |
static serial_t sconf[SERIAL_MAX]; |
static bool kb_enabled; |
static void serial_write(chardev_t *d, const char ch) |
static void serial_write(chardev_t *d, const char ch, bool silent) |
{ |
if (!silent) { |
serial_t *sd = (serial_t *)d->data; |
if (ch == '\n') |
serial_write(d, '\r'); |
serial_write(d, '\r', false); |
/* Wait until transmit buffer empty */ |
while (! (SERIAL_READ_LSR(sd->port) & (1<<TRANSMIT_EMPTY_BIT))) |
; |
while (!(SERIAL_READ_LSR(sd->port) & (1 << TRANSMIT_EMPTY_BIT))); |
SERIAL_WRITE(sd->port, ch); |
} |
} |
static void serial_enable(chardev_t *d) |
{ |
134,7 → 136,6 |
{ |
serial_t *sd = &sconf[0]; |
chardev_initialize("serial_console", &console, &serial_ops); |
console.data = sd; |
kb_enabled = true; |
147,8 → 148,7 |
irq_register(&serial_irq); |
/* I don't know why, but the serial interrupts simply |
* don't work on simics |
*/ |
don't work on simics */ |
virtual_timer_fnc = &serial_handler; |
stdin = &console; |
/branches/dynload/kernel/arch/mips32/src/drivers/msim.c |
---|
45,7 → 45,7 |
static chardev_t console; |
static irq_t msim_irq; |
static void msim_write(chardev_t *dev, const char ch); |
static void msim_write(chardev_t *dev, const char ch, bool silent); |
static void msim_enable(chardev_t *dev); |
static void msim_disable(chardev_t *dev); |
static char msim_do_read(chardev_t *dev); |
58,8 → 58,9 |
}; |
/** Putchar that works with MSIM & gxemul */ |
void msim_write(chardev_t *dev, const char ch) |
void msim_write(chardev_t *dev, const char ch, bool silent) |
{ |
if (!silent) |
*((char *) MSIM_VIDEORAM) = ch; |
} |