/branches/sparc/kernel/kernel.config |
---|
123,7 → 123,7 |
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_BPP (choice) |
# Support for SMP |
! [ARCH=ia32|ARCH=amd64|ARCH=ia32xen|ARCH=sparc64] CONFIG_SMP (y/n) |
! [ARCH=ia32|ARCH=amd64|ARCH=ia32xen|ARCH=sparc64|ARCH=ia64] CONFIG_SMP (y/n) |
# Improved support for hyperthreading |
! [(ARCH=ia32|ARCH=amd64|ARCH=ia32xen)&CONFIG_SMP=y] CONFIG_HT (y/n) |
144,7 → 144,7 |
! [ARCH=sparc64] CONFIG_Z8530 (y/n) |
# Support for NS16550 serial port |
! [ARCH=sparc64] CONFIG_NS16550 (y/n) |
! [ARCH=sparc64|ARCH=ia64] CONFIG_NS16550 (y/n) |
# Support for Serengeti console |
! [ARCH=sparc64] CONFIG_SGCN (y/n) |
/branches/sparc/kernel/genarch/include/kbd/ns16550.h |
---|
48,7 → 48,75 |
extern irq_ownership_t ns16550_claim(void); |
extern void ns16550_irq_handler(irq_t *irq, void *arg, ...); |
#include <arch/types.h> |
#ifndef ia64 |
#include <arch/drivers/kbd.h> |
#endif |
/* NS16550 registers */ |
#define RBR_REG 0 /** Receiver Buffer Register. */ |
#define IER_REG 1 /** Interrupt Enable Register. */ |
#define IIR_REG 2 /** Interrupt Ident Register (read). */ |
#define FCR_REG 2 /** FIFO control register (write). */ |
#define LCR_REG 3 /** Line Control register. */ |
#define LSR_REG 5 /** Line Status Register. */ |
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */ |
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */ |
/** Structure representing the ns16550 device. */ |
typedef struct { |
devno_t devno; |
volatile ioport_t io_port; /** Memory mapped registers of the ns16550. */ |
} ns16550_t; |
static inline uint8_t ns16550_rbr_read(ns16550_t *dev) |
{ |
return inb(dev->io_port+RBR_REG); |
} |
static inline void ns16550_rbr_write(ns16550_t *dev, uint8_t v) |
{ |
outb(dev->io_port+RBR_REG,v); |
} |
static inline uint8_t ns16550_ier_read(ns16550_t *dev) |
{ |
return inb(dev->io_port+IER_REG); |
} |
static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v) |
{ |
outb(dev->io_port+IER_REG,v); |
} |
static inline uint8_t ns16550_iir_read(ns16550_t *dev) |
{ |
return inb(dev->io_port+IIR_REG); |
} |
static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v) |
{ |
outb(dev->io_port+FCR_REG,v); |
} |
static inline uint8_t ns16550_lcr_read(ns16550_t *dev) |
{ |
return inb(dev->io_port+LCR_REG); |
} |
static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v) |
{ |
outb(dev->io_port+LCR_REG,v); |
} |
static inline uint8_t ns16550_lsr_read(ns16550_t *dev) |
{ |
return inb(dev->io_port+LSR_REG); |
} |
#endif |
/** @} |
*/ |
/branches/sparc/kernel/genarch/src/kbd/ns16550.c |
---|
38,8 → 38,10 |
#include <genarch/kbd/key.h> |
#include <genarch/kbd/scanc.h> |
#include <genarch/kbd/scanc_sun.h> |
#ifndef ia64 |
#include <arch/drivers/kbd.h> |
#include <arch/drivers/ns16550.h> |
#endif |
#include <ddi/irq.h> |
#include <ipc/irq.h> |
#include <cpu.h> |
109,13 → 111,13 |
* @param inr Interrupt number. |
* @param vaddr Virtual address of device's registers. |
*/ |
void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr) |
void ns16550_init(devno_t devno, inr_t inr, ioport_t port) |
{ |
chardev_initialize("ns16550_kbd", &kbrd, &ops); |
stdin = &kbrd; |
ns16550.devno = devno; |
ns16550.reg = (uint8_t *) vaddr; |
ns16550.io_port = port; |
irq_initialize(&ns16550_irq); |
ns16550_irq.devno = devno; |
125,10 → 127,21 |
irq_register(&ns16550_irq); |
sysinfo_set_item_val("kbd", NULL, true); |
#ifndef ia64 |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
#endif |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr); |
sysinfo_set_item_val("kbd.address.virtual", NULL, port); |
#ifdef ia64 |
uint8_t c; |
c = ns16550_lcr_read(&ns16550); |
ns16550_lcr_write(&ns16550, 0x80 | c); |
ns16550_rbr_write(&ns16550, 0x0c); |
ns16550_ier_write(&ns16550, 0x00); |
ns16550_lcr_write(&ns16550, c); |
#endif |
ns16550_grab(); |
} |
152,6 → 165,7 |
{ |
} |
char ns16550_key_read(chardev_t *d) |
{ |
char ch; |
161,6 → 175,7 |
while (!(ns16550_lsr_read(&ns16550) & LSR_DATA_READY)) |
; |
x = ns16550_rbr_read(&ns16550); |
#ifndef ia64 |
if (x != IGNORE_CODE) { |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
167,6 → 182,15 |
else |
active_read_key_pressed(x); |
} |
#else |
extern chardev_t kbrd; |
if(x != 0x0d) { |
if(x == 0x7f) |
x = '\b'; |
chardev_push_character(&kbrd, x); |
} |
#endif |
} |
return ch; |
} |
201,6 → 225,7 |
uint8_t x; |
x = ns16550_rbr_read(&ns16550); |
#ifndef ia64 |
if (x != IGNORE_CODE) { |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
207,6 → 232,15 |
else |
key_pressed(x); |
} |
#else |
extern chardev_t kbrd; |
if(x != 0x0d) { |
if (x == 0x7f) |
x = '\b'; |
chardev_push_character(&kbrd, x); |
} |
#endif |
} |
} |
/branches/sparc/kernel/genarch/src/kbd/key.c |
---|
39,9 → 39,13 |
#ifdef CONFIG_I8042 |
#include <genarch/kbd/scanc_pc.h> |
#endif |
#if (defined(sparc64)) |
#if (defined(CONFIG_Z8530) || defined(CONFIG_NS16550)) |
#include <genarch/kbd/scanc_sun.h> |
#endif |
#endif |
#include <synch/spinlock.h> |
#include <console/chardev.h> |
#include <macros.h> |
/branches/sparc/kernel/generic/include/proc/task.h |
---|
54,6 → 54,8 |
#include <proc/scheduler.h> |
#include <udebug/udebug.h> |
#define TASK_NAME_BUFLEN 20 |
struct thread; |
/** Task structure. */ |
67,8 → 69,8 |
* threads. |
*/ |
SPINLOCK_DECLARE(lock); |
char *name; |
char name[TASK_NAME_BUFLEN]; |
/** List of threads contained in this task. */ |
link_t th_head; |
/** Address space. */ |
/branches/sparc/kernel/generic/include/proc/program.h |
---|
52,12 → 52,15 |
extern void *program_loader; |
extern void program_create(as_t *as, uintptr_t entry_addr, program_t *p); |
extern int program_create_from_image(void *image_addr, program_t *p); |
extern int program_create_loader(program_t *p); |
extern void program_create(as_t *as, uintptr_t entry_addr, char *name, |
program_t *p); |
extern int program_create_from_image(void *image_addr, char *name, |
program_t *p); |
extern int program_create_loader(program_t *p, char *name); |
extern void program_ready(program_t *p); |
extern unative_t sys_program_spawn_loader(int *uspace_phone_id); |
extern unative_t sys_program_spawn_loader(int *uspace_phone_id, |
char *uspace_name, size_t name_len); |
#endif |
/branches/sparc/kernel/generic/include/proc/thread.h |
---|
259,7 → 259,8 |
extern slab_cache_t *fpu_context_slab; |
/* Thread syscall prototypes. */ |
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, thread_id_t *uspace_thread_id); |
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg, |
char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id); |
extern unative_t sys_thread_exit(int uspace_status); |
extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id); |
/branches/sparc/kernel/generic/include/synch/spinlock.h |
---|
36,6 → 36,7 |
#define KERN_SPINLOCK_H_ |
#include <arch/types.h> |
#include <arch/barrier.h> |
#include <preemption.h> |
#include <atomic.h> |
#include <debug.h> |
/branches/sparc/kernel/generic/include/stdarg.h |
---|
45,7 → 45,7 |
#define va_start(ap, last) __builtin_va_start(ap, last) |
#define va_arg(ap, type) __builtin_va_arg(ap, type) |
#define va_end(ap) __builtin_va_end(ap) |
#define va_copy(dst,src) __builtin_va_copy(dst,src) |
#define va_copy(dst, src) __builtin_va_copy(dst, src) |
#endif |
/branches/sparc/kernel/generic/src/main/kinit.c |
---|
169,7 → 169,7 |
} |
int rc = program_create_from_image((void *) init.tasks[i].addr, |
&programs[i]); |
"init-bin", &programs[i]); |
if (rc == 0 && programs[i].task != NULL) { |
/* |
/branches/sparc/kernel/generic/src/main/main.c |
---|
329,6 → 329,7 |
* collide with another CPU coming up. To prevent this, we |
* switch to this cpu's private stack prior to waking kmp up. |
*/ |
context_save(&CPU->saved_context); |
context_set(&CPU->saved_context, FADDR(main_ap_separated_stack), |
(uintptr_t) CPU->stack, CPU_STACK_SIZE); |
context_restore(&CPU->saved_context); |
/branches/sparc/kernel/generic/src/proc/task.c |
---|
130,7 → 130,7 |
/** Create new task with no threads. |
* |
* @param as Task's address space. |
* @param name Symbolic name. |
* @param name Symbolic name (a copy is made). |
* |
* @return New task's structure. |
* |
148,7 → 148,10 |
spinlock_initialize(&ta->lock, "task_ta_lock"); |
list_initialize(&ta->th_head); |
ta->as = as; |
ta->name = name; |
memcpy(ta->name, name, TASK_NAME_BUFLEN); |
ta->name[TASK_NAME_BUFLEN - 1] = '\0'; |
atomic_set(&ta->refcount, 0); |
atomic_set(&ta->lifecount, 0); |
ta->context = CONTEXT; |
/branches/sparc/kernel/generic/src/proc/program.c |
---|
67,9 → 67,10 |
* |
* @param as Address space containing a binary program image. |
* @param entry_addr Program entry-point address in program address space. |
* @param name Name to set for the program's task. |
* @param p Buffer for storing program information. |
*/ |
void program_create(as_t *as, uintptr_t entry_addr, program_t *p) |
void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p) |
{ |
as_area_t *a; |
uspace_arg_t *kernel_uarg; |
81,7 → 82,7 |
kernel_uarg->uspace_thread_arg = NULL; |
kernel_uarg->uspace_uarg = NULL; |
p->task = task_create(as, "app"); |
p->task = task_create(as, name); |
ASSERT(p->task); |
/* |
106,6 → 107,7 |
* executable image. The task is returned in *task. |
* |
* @param image_addr Address of an executable program image. |
* @param name Name to set for the program's task. |
* @param p Buffer for storing program info. If image_addr |
* points to a loader image, p->task will be set to |
* NULL and EOK will be returned. |
112,7 → 114,7 |
* |
* @return EOK on success or negative error code. |
*/ |
int program_create_from_image(void *image_addr, program_t *p) |
int program_create_from_image(void *image_addr, char *name, program_t *p) |
{ |
as_t *as; |
unsigned int rc; |
136,7 → 138,7 |
return EOK; |
} |
program_create(as, ((elf_header_t *) image_addr)->e_entry, p); |
program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p); |
return EOK; |
} |
143,10 → 145,12 |
/** Create a task from the program loader image. |
* |
* @param p Buffer for storing program info. |
* @param p Buffer for storing program info. |
* @param name Name to set for the program's task. |
* |
* @return EOK on success or negative error code. |
*/ |
int program_create_loader(program_t *p) |
int program_create_loader(program_t *p, char *name) |
{ |
as_t *as; |
unsigned int rc; |
167,7 → 171,8 |
return ENOENT; |
} |
program_create(as, ((elf_header_t *) program_loader)->e_entry, p); |
program_create(as, ((elf_header_t *) program_loader)->e_entry, |
name, p); |
return EOK; |
} |
188,16 → 193,20 |
* Creates a new task from the program loader image, connects a phone |
* to it and stores the phone id into the provided buffer. |
* |
* @param uspace_phone_id Userspace address where to store the phone id. |
* @param uspace_phone_id Userspace address where to store the phone id. |
* @param name Name to set on the new task (typically the same |
* as the command used to execute it). |
* |
* @return 0 on success or an error code from @ref errno.h. |
*/ |
unative_t sys_program_spawn_loader(int *uspace_phone_id) |
unative_t sys_program_spawn_loader(int *uspace_phone_id, char *uspace_name, |
size_t name_len) |
{ |
program_t p; |
int fake_id; |
int rc; |
int phone_id; |
char namebuf[TASK_NAME_BUFLEN]; |
fake_id = 0; |
207,11 → 216,26 |
if (rc != 0) |
return rc; |
/* Cap length of name and copy it from userspace. */ |
if (name_len > THREAD_NAME_BUFLEN - 1) |
name_len = THREAD_NAME_BUFLEN - 1; |
rc = copy_from_uspace(namebuf, uspace_name, name_len); |
if (rc != 0) |
return (unative_t) rc; |
namebuf[name_len] = '\0'; |
/* Allocate the phone for communicating with the new task. */ |
phone_id = phone_alloc(); |
if (phone_id < 0) |
return ELIMIT; |
rc = program_create_loader(&p); |
/* Spawn the new task. */ |
rc = program_create_loader(&p, namebuf); |
if (rc != 0) |
return rc; |
/branches/sparc/kernel/generic/src/proc/thread.c |
---|
279,7 → 279,7 |
* guarantee that the task won't cease to exist during the |
* call. The task's lock may not be held. |
* @param flags Thread flags. |
* @param name Symbolic name. |
* @param name Symbolic name (a copy is made). |
* @param uncounted Thread's accounting doesn't affect accumulated task |
* accounting. |
* |
316,6 → 316,7 |
interrupts_restore(ipl); |
memcpy(t->name, name, THREAD_NAME_BUFLEN); |
t->name[THREAD_NAME_BUFLEN - 1] = '\0'; |
t->thread_code = func; |
t->thread_arg = arg; |
708,7 → 709,7 |
* |
*/ |
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, |
thread_id_t *uspace_thread_id) |
size_t name_len, thread_id_t *uspace_thread_id) |
{ |
thread_t *t; |
char namebuf[THREAD_NAME_BUFLEN]; |
715,10 → 716,15 |
uspace_arg_t *kernel_uarg; |
int rc; |
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN); |
if (name_len > THREAD_NAME_BUFLEN - 1) |
name_len = THREAD_NAME_BUFLEN - 1; |
rc = copy_from_uspace(namebuf, uspace_name, name_len); |
if (rc != 0) |
return (unative_t) rc; |
namebuf[name_len] = '\0'; |
/* |
* In case of failure, kernel_uarg will be deallocated in this function. |
* In case of success, kernel_uarg will be freed in uinit(). |
/branches/sparc/kernel/generic/src/mm/tlb.c |
---|
134,7 → 134,9 |
void tlb_shootdown_ipi_send(void) |
{ |
#ifndef ia64 |
ipi_broadcast(VECTOR_TLB_SHOOTDOWN_IPI); |
#endif |
} |
/** Receive TLB shootdown message. */ |
/branches/sparc/kernel/generic/src/ipc/kbox.c |
---|
45,6 → 45,7 |
void ipc_kbox_cleanup(void) |
{ |
ipl_t ipl; |
bool have_kb_thread; |
/* Only hold kb_cleanup_lock while setting kb_finished - this is enough */ |
63,6 → 64,17 |
* wake up and terminate. |
*/ |
ipc_answerbox_slam_phones(&TASK->kernel_box, have_kb_thread); |
/* |
* If the task was being debugged, clean up debugging session. |
* This is necessarry as slamming the phones won't force |
* kbox thread to clean it up since sender != debugger. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
udebug_task_cleanup(TASK); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
if (have_kb_thread) { |
LOG("join kb_thread..\n"); |
79,13 → 91,75 |
spinlock_unlock(&TASK->kernel_box.lock); |
} |
/** Handle hangup message in kbox. |
* |
* @param call The IPC_M_PHONE_HUNGUP call structure. |
* @param last Output, the function stores @c true here if |
* this was the last phone, @c false otherwise. |
**/ |
static void kbox_proc_phone_hungup(call_t *call, bool *last) |
{ |
ipl_t ipl; |
LOG("kbox_proc_phone_hungup()\n"); |
/* Was it our debugger, who hung up? */ |
if (call->sender == TASK->udebug.debugger) { |
/* Terminate debugging session (if any) */ |
LOG("kbox: terminate debug session\n"); |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
udebug_task_cleanup(TASK); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} else { |
LOG("kbox: was not debugger\n"); |
} |
LOG("kbox: continue with hangup message\n"); |
IPC_SET_RETVAL(call->data, 0); |
ipc_answer(&TASK->kernel_box, call); |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
spinlock_lock(&TASK->answerbox.lock); |
if (list_empty(&TASK->answerbox.connected_phones)) { |
/* |
* Last phone has been disconnected. Detach this thread so it |
* gets freed and signal to the caller. |
*/ |
/* Only detach kbox thread unless already terminating. */ |
mutex_lock(&TASK->kb_cleanup_lock); |
if (&TASK->kb_finished == false) { |
/* Detach kbox thread so it gets freed from memory. */ |
thread_detach(TASK->kb_thread); |
TASK->kb_thread = NULL; |
} |
mutex_unlock(&TASK->kb_cleanup_lock); |
LOG("phone list is empty\n"); |
*last = true; |
} else { |
*last = false; |
} |
spinlock_unlock(&TASK->answerbox.lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} |
/** Implementing function for the kbox thread. |
* |
* This function listens for debug requests. It terminates |
* when all phones are disconnected from the kbox. |
* |
* @param arg Ignored. |
*/ |
static void kbox_thread_proc(void *arg) |
{ |
call_t *call; |
int method; |
bool done; |
ipl_t ipl; |
(void)arg; |
LOG("kbox_thread_proc()\n"); |
95,46 → 169,28 |
call = ipc_wait_for_call(&TASK->kernel_box, SYNCH_NO_TIMEOUT, |
SYNCH_FLAGS_NONE); |
if (call != NULL) { |
method = IPC_GET_METHOD(call->data); |
if (call == NULL) |
continue; /* Try again. */ |
if (method == IPC_M_DEBUG_ALL) { |
udebug_call_receive(call); |
} |
switch (IPC_GET_METHOD(call->data)) { |
if (method == IPC_M_PHONE_HUNGUP) { |
LOG("kbox: handle hangup message\n"); |
case IPC_M_DEBUG_ALL: |
/* Handle debug call. */ |
udebug_call_receive(call); |
break; |
/* Was it our debugger, who hung up? */ |
if (call->sender == TASK->udebug.debugger) { |
/* Terminate debugging session (if any) */ |
LOG("kbox: terminate debug session\n"); |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
udebug_task_cleanup(TASK); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} else { |
LOG("kbox: was not debugger\n"); |
} |
case IPC_M_PHONE_HUNGUP: |
/* |
* Process the hangup call. If this was the last |
* phone, done will be set to true and the |
* while loop will terminate. |
*/ |
kbox_proc_phone_hungup(call, &done); |
break; |
LOG("kbox: continue with hangup message\n"); |
IPC_SET_RETVAL(call->data, 0); |
ipc_answer(&TASK->kernel_box, call); |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
spinlock_lock(&TASK->answerbox.lock); |
if (list_empty(&TASK->answerbox.connected_phones)) { |
/* Last phone has been disconnected */ |
TASK->kb_thread = NULL; |
done = true; |
LOG("phone list is empty\n"); |
} |
spinlock_unlock(&TASK->answerbox.lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} |
default: |
/* Ignore */ |
break; |
} |
} |
/branches/sparc/kernel/arch/sparc64/include/types.h |
---|
54,6 → 54,8 |
typedef uint64_t ipl_t; |
typedef uint64_t ioport_t; |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
/branches/sparc/kernel/arch/sparc64/include/asm.h |
---|
42,7 → 42,56 |
#include <arch/register.h> |
#include <config.h> |
#include <arch/stack.h> |
#include <arch/barrier.h> |
static inline void outb(ioport_t port, uint8_t v) |
{ |
*((volatile uint8_t *)(port)) = v; |
memory_barrier(); |
} |
static inline void outw(ioport_t port, uint16_t v) |
{ |
*((volatile uint16_t *)(port)) = v; |
memory_barrier(); |
} |
static inline void outl(ioport_t port, uint32_t v) |
{ |
*((volatile uint32_t *)(port)) = v; |
memory_barrier(); |
} |
static inline uint8_t inb(ioport_t port) |
{ |
uint8_t rv; |
rv = *((volatile uint8_t *)(port)); |
memory_barrier(); |
return rv; |
} |
static inline uint16_t inw(ioport_t port) |
{ |
uint16_t rv; |
rv = *((volatile uint16_t *)(port)); |
memory_barrier(); |
return rv; |
} |
static inline uint32_t inl(ioport_t port) |
{ |
uint32_t rv; |
rv = *((volatile uint32_t *)(port)); |
memory_barrier(); |
return rv; |
} |
/** Read Processor State register. |
* |
* @return Value of PSTATE register. |
/branches/sparc/kernel/arch/sparc64/include/drivers/ns16550.h |
---|
35,67 → 35,7 |
#ifndef KERN_sparc64_NS16550_H_ |
#define KERN_sparc64_NS16550_H_ |
#include <arch/types.h> |
#include <arch/drivers/kbd.h> |
/* NS16550 registers */ |
#define RBR_REG 0 /** Receiver Buffer Register. */ |
#define IER_REG 1 /** Interrupt Enable Register. */ |
#define IIR_REG 2 /** Interrupt Ident Register (read). */ |
#define FCR_REG 2 /** FIFO control register (write). */ |
#define LCR_REG 3 /** Line Control register. */ |
#define LSR_REG 5 /** Line Status Register. */ |
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */ |
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */ |
/** Structure representing the ns16550 device. */ |
typedef struct { |
devno_t devno; |
volatile uint8_t *reg; /** Memory mapped registers of the ns16550. */ |
} ns16550_t; |
static inline uint8_t ns16550_rbr_read(ns16550_t *dev) |
{ |
return dev->reg[RBR_REG]; |
} |
static inline uint8_t ns16550_ier_read(ns16550_t *dev) |
{ |
return dev->reg[IER_REG]; |
} |
static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[IER_REG] = v; |
} |
static inline uint8_t ns16550_iir_read(ns16550_t *dev) |
{ |
return dev->reg[IIR_REG]; |
} |
static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[FCR_REG] = v; |
} |
static inline uint8_t ns16550_lcr_read(ns16550_t *dev) |
{ |
return dev->reg[LCR_REG]; |
} |
static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[LCR_REG] = v; |
} |
static inline uint8_t ns16550_lsr_read(ns16550_t *dev) |
{ |
return dev->reg[LSR_REG]; |
} |
#endif |
/** @} |
/branches/sparc/kernel/arch/sparc64/src/drivers/kbd.c |
---|
147,7 → 147,7 |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_init(devno, inr, vaddr); |
ns16550_init(devno, inr, (ioport_t)vaddr); |
break; |
#endif |
default: |
/branches/sparc/kernel/arch/ia64/include/atomic.h |
---|
51,6 → 51,20 |
return v; |
} |
static inline uint64_t test_and_set(atomic_t *val) { |
uint64_t v; |
asm volatile ( |
"movl %0=0x01;;\n" |
"xchg8 %0=%1,%0;;\n" |
: "=r" (v),"+m" (val->count) |
); |
return v; |
} |
static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); } |
static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); } |
/branches/sparc/kernel/arch/ia64/include/bootinfo.h |
---|
29,8 → 29,8 |
#ifndef KERN_ia64_BOOTINFO_H_ |
#define KERN_ia64_BOOTINFO_H_ |
#define BOOTINFO_ADDRESS 0x4401000 |
#define CONFIG_INIT_TASKS 32 |
typedef struct { |
46,6 → 46,12 |
typedef struct { |
binit_t taskmap; |
unsigned long * sapic; |
unsigned long sys_freq; |
unsigned long freq_scale; |
unsigned int wakeup_intno; |
} bootinfo_t; |
extern bootinfo_t *bootinfo; |
/branches/sparc/kernel/arch/ia64/include/asm.h |
---|
39,10 → 39,11 |
#include <arch/types.h> |
#include <arch/register.h> |
typedef uint64_t ioport_t; |
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL |
static inline void outb(uint64_t port,uint8_t v) |
static inline void outb(ioport_t port,uint8_t v) |
{ |
*((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
49,7 → 50,7 |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void outw(uint64_t port,uint16_t v) |
static inline void outw(ioport_t port,uint16_t v) |
{ |
*((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
56,7 → 57,7 |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void outl(uint64_t port,uint32_t v) |
static inline void outl(ioport_t port,uint32_t v) |
{ |
*((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
65,7 → 66,7 |
static inline uint8_t inb(uint64_t port) |
static inline uint8_t inb(ioport_t port) |
{ |
asm volatile ("mf\n" ::: "memory"); |
72,7 → 73,7 |
return *((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))); |
} |
static inline uint16_t inw(uint64_t port) |
static inline uint16_t inw(ioport_t port) |
{ |
asm volatile ("mf\n" ::: "memory"); |
79,7 → 80,7 |
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xffE) | ( (port >> 2) << 12 )))); |
} |
static inline uint32_t inl(uint64_t port) |
static inline uint32_t inl(ioport_t port) |
{ |
asm volatile ("mf\n" ::: "memory"); |
98,9 → 99,14 |
{ |
uint64_t v; |
asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
//I'm not sure why but this code bad inlines in scheduler, |
//so THE shifts about 16B and causes kernel panic |
//asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
//return v; |
return v; |
//this code have the same meaning but inlines well |
asm volatile ("mov %0 = r12" : "=r" (v) ); |
return v & (~(STACK_SIZE-1)); |
} |
/** Return Processor State Register. |
152,6 → 158,16 |
return v; |
} |
static inline uint64_t cr64_read(void) |
{ |
uint64_t v; |
asm volatile ("mov %0 = cr64\n" : "=r" (v)); |
return v; |
} |
/** Write ITC (Interval Timer Counter) register. |
* |
* @param v New counter value. |
/branches/sparc/kernel/arch/ia64/include/mm/page.h |
---|
46,8 → 46,20 |
/** Bit width of the TLB-locked portion of kernel address space. */ |
#define KERNEL_PAGE_WIDTH 28 /* 256M */ |
#define IO_PAGE_WIDTH 26 /* 64M */ |
#define FW_PAGE_WIDTH 28 /* 256M */ |
/** Staticly mapped IO spaces */ |
/* Firmware area (bellow 4GB in phys mem) */ |
#define FW_OFFSET 0x00000000F0000000 |
/* Legacy IO space */ |
#define IO_OFFSET 0x0001000000000000 |
/* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000*/ |
#define VIO_OFFSET 0x0002000000000000 |
#define PPN_SHIFT 12 |
#define VRN_SHIFT 61 |
/branches/sparc/kernel/arch/ia64/include/cpu.h |
---|
38,6 → 38,7 |
#include <arch/types.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#include <arch/bootinfo.h> |
#define FAMILY_ITANIUM 0x7 |
#define FAMILY_ITANIUM2 0x1f |
63,6 → 64,33 |
return v; |
} |
#define CR64_ID_SHIFT 24 |
#define CR64_ID_MASK 0xff000000 |
#define CR64_EID_SHIFT 16 |
#define CR64_EID_MASK 0xff0000 |
static inline int ia64_get_cpu_id(void) |
{ |
uint64_t cr64=cr64_read(); |
return ((CR64_ID_MASK)&cr64)>>CR64_ID_SHIFT; |
} |
static inline int ia64_get_cpu_eid(void) |
{ |
uint64_t cr64=cr64_read(); |
return ((CR64_EID_MASK)&cr64)>>CR64_EID_SHIFT; |
} |
static inline void ipi_send_ipi(int id,int eid,int intno) |
{ |
(bootinfo->sapic)[2*(id*256+eid)]=intno; |
} |
#endif |
/** @} |
/branches/sparc/kernel/arch/ia64/include/drivers/it.h |
---|
41,7 → 41,7 |
* from firmware. |
* |
*/ |
#define IT_DELTA 100000 |
#define IT_DELTA it_delta |
extern void it_init(void); |
/branches/sparc/kernel/arch/ia64/Makefile.inc |
---|
82,6 → 82,7 |
arch/$(ARCH)/src/mm/vhpt.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/smp/smp.c \ |
arch/$(ARCH)/src/drivers/it.c |
ifeq ($(MACHINE),ski) |
98,3 → 99,7 |
BFD = binary |
endif |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
/branches/sparc/kernel/arch/ia64/src/ia64.c |
---|
54,7 → 54,17 |
#include <arch/drivers/ega.h> |
#include <arch/bootinfo.h> |
#include <genarch/kbd/i8042.h> |
#include <genarch/kbd/ns16550.h> |
#include <smp/smp.h> |
#include <smp/ipi.h> |
#include <arch/atomic.h> |
#include <panic.h> |
#include <print.h> |
/*NS16550 as a COM 1*/ |
#define NS16550_IRQ 4 |
#define NS16550_PORT 0x3f8 |
bootinfo_t *bootinfo; |
void arch_pre_main(void) |
102,12 → 112,15 |
void arch_post_mm_init(void) |
{ |
irq_init(INR_COUNT, INR_COUNT); |
if(config.cpu_active==1) |
{ |
irq_init(INR_COUNT, INR_COUNT); |
#ifdef SKI |
ski_init_console(); |
ski_init_console(); |
#else |
ega_init(); |
ega_init(); |
#endif |
} |
it_init(); |
} |
127,6 → 140,9 |
{ |
while (1) { |
i8042_poll(); |
#ifdef CONFIG_NS16550 |
ns16550_poll(); |
#endif |
thread_usleep(POLL_INTERVAL); |
} |
} |
135,7 → 151,7 |
void arch_post_smp_init(void) |
{ |
if (config.cpu_active == 1) { |
{ |
/* |
* Create thread that polls keyboard. |
*/ |
153,6 → 169,10 |
/* keyboard controller */ |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
#ifdef CONFIG_NS16550 |
ns16550_init(kbd, NS16550_IRQ, NS16550_PORT); // as a COM 1 |
#else |
#endif |
thread_t *t; |
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
164,6 → 184,7 |
} |
} |
/** Enter userspace and never return. */ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
224,7 → 245,7 |
void arch_reboot(void) |
{ |
// TODO |
outb(0x64,0xfe); |
while (1); |
} |
/branches/sparc/kernel/arch/ia64/src/start.S |
---|
39,12 → 39,10 |
#define KERNEL_TRANSLATION_D 0x0010000000000661 |
#define KERNEL_TRANSLATION_VIO 0x0010000000000671 |
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671 |
#define VIO_OFFSET 0x0002000000000000 |
#define KERNEL_TRANSLATION_FW 0x00100000F0000671 |
#define IO_OFFSET 0x0001000000000000 |
.section K_TEXT_START, "ax" |
.global kernel_image_start |
53,6 → 51,18 |
kernel_image_start: |
.auto |
#identifi self(CPU) in OS structures by ID / EID |
mov r9=cr64 |
mov r10=1 |
movl r12=0xffffffff |
movl r8=cpu_by_id_eid_list |
and r8=r8,r12 |
shr r9=r9,16 |
add r8=r8,r9 |
st1 [r8]=r10 |
mov psr.l = r0 |
srlz.i |
srlz.d |
114,8 → 124,25 |
itr.d dtr[r7] = r10 |
#setup mapping for fimware arrea (also SAPIC) |
mov r11 = cr.itir ;; |
movl r10 = ~0xfc;; |
and r10 =r10 , r11 ;; |
movl r11 = (FW_PAGE_WIDTH << PS_SHIFT);; |
or r10 =r10 , r11 ;; |
mov cr.itir = r10;; |
movl r7 = 3 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET |
mov cr.ifa = r8 |
movl r10 = (KERNEL_TRANSLATION_FW) |
itr.d dtr[r7] = r10 |
# initialize PSR |
movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK) /* Enable paging */ |
mov r9 = psr |
142,6 → 169,12 |
# switch to register bank 1 |
bsw.1 |
#Am'I BSP or AP |
movl r20=bsp_started;; |
ld8 r20=[r20];; |
cmp.eq p3,p2=r20,r0;; |
# initialize register stack |
mov ar.rsc = r0 |
160,25 → 193,35 |
movl r1 = _hardcoded_load_address |
/* |
* Initialize hardcoded_* variables. |
* Initialize hardcoded_* variables. Do only BSP |
*/ |
movl r14 = _hardcoded_ktext_size |
movl r15 = _hardcoded_kdata_size |
movl r16 = _hardcoded_load_address ;; |
addl r17 = @gprel(hardcoded_ktext_size), gp |
addl r18 = @gprel(hardcoded_kdata_size), gp |
addl r19 = @gprel(hardcoded_load_address), gp |
addl r21 = @gprel(bootinfo), gp |
(p3) movl r14 = _hardcoded_ktext_size |
(p3) movl r15 = _hardcoded_kdata_size |
(p3) movl r16 = _hardcoded_load_address ;; |
(p3) addl r17 = @gprel(hardcoded_ktext_size), gp |
(p3) addl r18 = @gprel(hardcoded_kdata_size), gp |
(p3) addl r19 = @gprel(hardcoded_load_address), gp |
(p3) addl r21 = @gprel(bootinfo), gp |
;; |
st8 [r17] = r14 |
st8 [r18] = r15 |
st8 [r19] = r16 |
st8 [r21] = r20 |
(p3) st8 [r17] = r14 |
(p3) st8 [r18] = r15 |
(p3) st8 [r19] = r16 |
(p3) st8 [r21] = r20 |
ssm (1 << 19) ;; /* Disable f32 - f127 */ |
srlz.i |
srlz.d ;; |
(p2) movl r18 = main_ap ;; |
(p2) mov b1 = r18 ;; |
(p2) br.call.sptk.many b0 = b1 |
#Mark that BSP is on |
mov r20=1;; |
movl r21=bsp_started;; |
st8 [r21]=r20;; |
br.call.sptk.many b0 = arch_pre_main |
movl r18 = main_bsp ;; |
188,3 → 231,46 |
0: |
br 0b |
.align 4096 |
kernel_image_ap_start: |
.auto |
#identifi self(CPU) in OS structures by ID / EID |
mov r9=cr64 |
mov r10=1 |
movl r12=0xffffffff |
movl r8=cpu_by_id_eid_list |
and r8=r8,r12 |
shr r9=r9,16 |
add r8=r8,r9 |
st1 [r8]=r10 |
#wait for wakeup sychro signal (#3 in cpu_by_id_eid_list) |
kernel_image_ap_start_loop: |
movl r11=kernel_image_ap_start_loop |
and r11=r11,r12 |
mov b1 = r11 |
ld1 r20=[r8];; |
movl r21=3;; |
cmp.eq p2,p3=r20,r21;; |
(p3)br.call.sptk.many b0 = b1 |
movl r11=kernel_image_start |
and r11=r11,r12 |
mov b1 = r11 |
br.call.sptk.many b0 = b1 |
.align 16 |
.global bsp_started |
bsp_started: |
.space 8 |
.align 4096 |
.global cpu_by_id_eid_list |
cpu_by_id_eid_list: |
.space 65536 |
/branches/sparc/kernel/arch/ia64/src/smp/smp.c |
---|
0,0 → 1,174 |
/* |
* Copyright (c) 2005 Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch.h> |
#include <arch/ski/ski.h> |
#include <arch/drivers/it.h> |
#include <arch/interrupt.h> |
#include <arch/barrier.h> |
#include <arch/asm.h> |
#include <arch/register.h> |
#include <arch/types.h> |
#include <arch/context.h> |
#include <arch/stack.h> |
#include <arch/mm/page.h> |
#include <mm/as.h> |
#include <config.h> |
#include <userspace.h> |
#include <console/console.h> |
#include <proc/uarg.h> |
#include <syscall/syscall.h> |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#include <arch/drivers/ega.h> |
#include <arch/bootinfo.h> |
#include <genarch/kbd/i8042.h> |
#include <genarch/kbd/ns16550.h> |
#include <smp/smp.h> |
#include <smp/ipi.h> |
#include <arch/atomic.h> |
#include <panic.h> |
#include <print.h> |
#ifdef CONFIG_SMP |
extern char cpu_by_id_eid_list[256][256]; |
static void sapic_init(void) |
{ |
bootinfo->sapic=(unative_t *)(PA2KA((unative_t)(bootinfo->sapic))|FW_OFFSET); |
} |
static void ipi_broadcast_arch_all(int ipi ) |
{ |
int id,eid; |
int myid,myeid; |
myid=ia64_get_cpu_id(); |
myeid=ia64_get_cpu_eid(); |
printf("Not sending to ID:%d,EID:%d",myid,myeid); |
for(id=0;id<256;id++) |
for(eid=0;eid<256;eid++) |
if((id!=myid) || (eid!=myeid)) |
ipi_send_ipi(id,eid,ipi); |
} |
void ipi_broadcast_arch(int ipi ) |
{ |
ipi_broadcast_arch_all(ipi); |
} |
void smp_init(void) |
{ |
sapic_init(); |
ipi_broadcast_arch_all(bootinfo->wakeup_intno); |
volatile long long brk; |
for(brk=0;brk<100LL*1024LL*1024LL;brk++); //wait a while before CPUs starts |
config.cpu_count=0; |
int id,eid; |
for(id=0;id<256;id++) |
for(eid=0;eid<256;eid++) |
if(cpu_by_id_eid_list[id][eid]==1){ |
config.cpu_count++; |
printf("Found CPU ID:%d EDI:%d\n",id,eid); |
cpu_by_id_eid_list[id][eid]=2; |
} |
} |
void kmp(void *arg __attribute__((unused))) |
{ |
int id,eid; |
int myid,myeid; |
myid=ia64_get_cpu_id(); |
myeid=ia64_get_cpu_eid(); |
for(id=0;id<256;id++) |
for(eid=0;eid<256;eid++) |
if((id!=myid) || (eid!=myeid)) |
if(cpu_by_id_eid_list[id][eid]!=0){ |
if(cpu_by_id_eid_list[id][eid]==1){ |
//config.cpu_count++; |
//cpu_by_id_eid_list[id][eid]=2; |
printf("Found Late CPU ID:%d EDI:%d Not added to system!!!\n",id,eid); |
continue; |
} |
cpu_by_id_eid_list[id][eid]=3; |
/* |
* There may be just one AP being initialized at |
* the time. After it comes completely up, it is |
* supposed to wake us up. |
*/ |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, |
SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) { |
printf("%s: waiting for cpu ID:%d EID:%d" |
"timed out\n", __FUNCTION__, |
id, eid); |
} |
} |
} |
#endif |
/*This is just a hack for linking with assembler - may be removed in future*/ |
#ifndef CONFIG_SMP |
void main_ap(void); |
void main_ap(void) |
{ |
while(1); |
} |
#endif |
/** @} |
*/ |
/branches/sparc/kernel/arch/ia64/src/mm/frame.c |
---|
42,20 → 42,31 |
* for real ia64 systems that provide memory map. |
*/ |
#define MEMORY_SIZE (64 * 1024 * 1024) |
#define MEMORY_BASE (64 * 1024 * 1024) |
#define MEMORY_BASE (0 * 64 * 1024 * 1024) |
#define ONE_TO_ONE_MAPPING_SIZE (256*1048576) // Mapped at start |
#define ROM_BASE 0xa0000 //For ski |
#define ROM_SIZE (384 * 1024) //For ski |
void poke_char(int x,int y,char ch, char c); |
uintptr_t last_frame; |
void frame_arch_init(void) |
{ |
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0); |
if(config.cpu_active==1) |
{ |
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0); |
/* |
* Blacklist ROM regions. |
*/ |
frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE)); |
/* |
* Blacklist ROM regions. |
*/ |
//frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE)); |
frame_mark_unavailable(ADDR2PFN(0), SIZE2FRAMES(1048576)); |
last_frame=SIZE2FRAMES((VRN_KERNEL<<VRN_SHIFT)+ONE_TO_ONE_MAPPING_SIZE); |
} |
} |
/** @} |
/branches/sparc/kernel/arch/ia64/src/mm/page.c |
---|
47,6 → 47,7 |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <memstr.h> |
#include <align.h> |
static void set_environment(void); |
262,5 → 263,27 |
v->present.tag.tag_word = tag; |
} |
extern uintptr_t last_frame; |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) { |
uintptr_t addr = PFN2ADDR(i); |
page_mapping_insert(AS_KERNEL, virtaddr + addr, physaddr + addr, PAGE_NOT_CACHEABLE | PAGE_WRITE); |
} |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
return virtaddr; |
} |
/** @} |
*/ |
/branches/sparc/kernel/arch/ia64/src/drivers/it.c |
---|
46,6 → 46,16 |
#define IT_SERVICE_CLOCKS 64 |
#define FREQ_NUMERATOR_SHIFT 32 |
#define FREQ_NUMERATOR_MASK 0xffffffff00000000LL |
#define FREQ_DENOMINATOR_SHIFT 0 |
#define FREQ_DENOMINATOR_MASK 0xffffffffLL |
uint64_t it_delta; |
static irq_t it_irq; |
static irq_ownership_t it_claim(void); |
55,14 → 65,25 |
void it_init(void) |
{ |
cr_itv_t itv; |
irq_initialize(&it_irq); |
it_irq.inr = INTERRUPT_TIMER; |
it_irq.devno = device_assign_devno(); |
it_irq.claim = it_claim; |
it_irq.handler = it_interrupt; |
irq_register(&it_irq); |
if(config.cpu_active==1) |
{ |
irq_initialize(&it_irq); |
it_irq.inr = INTERRUPT_TIMER; |
it_irq.devno = device_assign_devno(); |
it_irq.claim = it_claim; |
it_irq.handler = it_interrupt; |
irq_register(&it_irq); |
uint64_t base_freq; |
base_freq = ((bootinfo->freq_scale) & FREQ_NUMERATOR_MASK) >> FREQ_NUMERATOR_SHIFT; |
base_freq *= bootinfo->sys_freq; |
base_freq /= ((bootinfo->freq_scale) & FREQ_DENOMINATOR_MASK) >> FREQ_DENOMINATOR_SHIFT; |
it_delta = base_freq /HZ; |
} |
/* initialize Interval Timer external interrupt vector */ |
itv.value = itv_read(); |
itv.vector = INTERRUPT_TIMER; |
/branches/sparc/kernel/arch/ppc32/src/asm.S |
---|
66,9 → 66,9 |
mr sp, r4 |
# %r3 is defined to hold pcb_ptr - set it to 0 |
# %r6 is defined to hold pcb_ptr - set it to 0 |
xor r3, r3, r3 |
xor r6, r6, r6 |
# jump to userspace |
/branches/sparc/kernel/arch/ppc32/src/mm/tlb.c |
---|
96,7 → 96,6 |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfrc = rc; |
return NULL; |
default: |
/branches/sparc/kernel/arch/ppc64/src/mm/page.c |
---|
103,7 → 103,6 |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfrc = rc; |
return NULL; |
default: |
/branches/sparc/kernel/arch/mips32/src/mm/tlb.c |
---|
429,7 → 429,6 |
break; |
case AS_PF_FAULT: |
page_table_lock(AS, true); |
printf("Page fault.\n"); |
*pfrc = AS_PF_FAULT; |
return NULL; |
break; |