/trunk/kernel/arch/sparc64/include/boot/boot.h |
---|
83,10 → 83,15 |
} keyboard_t; |
typedef struct { |
uint32_t clock_frequency; |
} processor_t; |
typedef struct { |
taskmap_t taskmap; |
memmap_t memmap; |
screen_t screen; |
keyboard_t keyboard; |
processor_t processor; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
/trunk/kernel/arch/sparc64/include/asm.h |
---|
35,10 → 35,12 |
#ifndef KERN_sparc64_ASM_H_ |
#define KERN_sparc64_ASM_H_ |
#include <arch.h> |
#include <typedefs.h> |
#include <arch/types.h> |
#include <arch/register.h> |
#include <config.h> |
#include <time/clock.h> |
/** Read Processor State register. |
* |
335,7 → 337,7 |
extern void cpu_halt(void); |
extern void cpu_sleep(void); |
extern void asm_delay_loop(uint32_t t); |
extern void asm_delay_loop(const uint32_t usec); |
extern uint64_t read_from_ag_g7(void); |
extern void write_to_ag_g6(uint64_t val); |
/trunk/kernel/arch/sparc64/include/cpu.h |
---|
52,6 → 52,7 |
struct cpu_arch { |
ver_reg_t ver; |
uint32_t clock_frequency; |
}; |
#endif |
/trunk/kernel/arch/sparc64/include/drivers/tick.h |
---|
37,8 → 37,6 |
#include <typedefs.h> |
#define TICK_DELTA 500000 |
extern void tick_init(void); |
extern void tick_interrupt(int n, istate_t *istate); |
/trunk/kernel/arch/sparc64/src/sparc64.c |
---|
42,6 → 42,7 |
#include <console/console.h> |
#include <arch/boot/boot.h> |
#include <arch/arch.h> |
#include <arch/asm.h> |
#include <arch/mm/page.h> |
#include <arch/stack.h> |
#include <userspace.h> |
89,10 → 90,32 |
thread_ready(t); |
} |
/** Calibrate delay loop. |
* |
* On sparc64, we implement delay() by waiting for the TICK register to |
* reach a pre-computed value, as opposed to performing some pre-computed |
* amount of instructions of known duration. We set the delay_loop_const |
* to 1 in order to neutralize the multiplication done by delay(). |
*/ |
void calibrate_delay_loop(void) |
{ |
CPU->delay_loop_const = 1; |
} |
/** Wait several microseconds. |
* |
* We assume that interrupts are already disabled. |
* |
* @param t Microseconds to wait. |
*/ |
void asm_delay_loop(const uint32_t usec) |
{ |
uint64_t stop = tick_read() + (uint64_t) usec * (uint64_t) CPU->arch.clock_frequency / 1000000; |
while (tick_read() < stop) |
; |
} |
/** Switch to userspace. */ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
/trunk/kernel/arch/sparc64/src/cpu/cpu.c |
---|
32,14 → 32,16 |
/** @file |
*/ |
#include <arch/asm.h> |
#include <cpu.h> |
#include <arch.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#include <print.h> |
#include <arch/boot/boot.h> |
void cpu_arch_init(void) |
{ |
CPU->arch.clock_frequency = bootinfo.processor.clock_frequency; |
} |
void cpu_identify(void) |
93,7 → 95,8 |
break; |
} |
printf("cpu%d: manuf=%s, impl=%s, mask=%d\n", CPU->id, manuf, impl, CPU->arch.ver.mask); |
printf("cpu%d: manuf=%s, impl=%s, mask=%d (%dMHz)\n", |
CPU->id, manuf, impl, CPU->arch.ver.mask, CPU->arch.clock_frequency/1000000); |
} |
/** @} |
/trunk/kernel/arch/sparc64/src/dummy.s |
---|
28,7 → 28,6 |
.text |
.global asm_delay_loop |
.global cpu_sleep |
.global fpu_context_restore |
.global fpu_context_save |
38,7 → 37,6 |
.global dummy |
asm_delay_loop: |
cpu_sleep: |
fpu_context_restore: |
fpu_context_save: |
/trunk/kernel/arch/sparc64/src/drivers/tick.c |
---|
36,10 → 36,15 |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <arch/register.h> |
#include <typedefs.h> |
#include <arch/cpu.h> |
#include <arch/boot/boot.h> |
#include <time/clock.h> |
#include <arch.h> |
#include <debug.h> |
#include <time/clock.h> |
#include <typedefs.h> |
#define TICK_RESTART_TIME 50 /* Worst case estimate. */ |
/** Initialize tick interrupt. */ |
void tick_init(void) |
{ |
47,7 → 52,7 |
interrupt_register(14, "tick_int", tick_interrupt); |
compare.int_dis = false; |
compare.tick_cmpr = TICK_DELTA; |
compare.tick_cmpr = bootinfo.processor.clock_frequency/HZ; |
tick_compare_write(compare.value); |
tick_write(0); |
} |
60,6 → 65,7 |
void tick_interrupt(int n, istate_t *istate) |
{ |
softint_reg_t softint, clear; |
uint64_t next, compare, start, stop; |
softint.value = softint_read(); |
83,7 → 89,15 |
/* |
* Restart counter. |
*/ |
tick_write(0); |
compare = CPU->arch.clock_frequency/HZ; |
start = tick_read(); |
next = start - compare; |
while (next >= compare - TICK_RESTART_TIME) { |
next -= compare; |
CPU->missed_clock_ticks++; |
} |
stop = tick_read(); |
tick_write(next + (stop - start)); |
clock(); |
} |
/trunk/kernel/arch/sparc64/src/start.S |
---|
60,16 → 60,14 |
* Setup basic runtime environment. |
*/ |
flushw ! flush all but the active register window |
wrpr %g0, 0, %tl ! TL = 0, primary context register is used |
flushw ! flush all but the active register window |
! Disable interrupts and disable 32-bit address masking. |
rdpr %pstate, %g1 |
and %g1, ~(PSTATE_AM_BIT|PSTATE_IE_BIT), %g1 |
wrpr %g1, 0, %pstate |
wrpr %g0, 0, %tl ! TL = 0, primary context register is used |
wrpr %g0, 0, %pil ! intialize %pil |
wrpr %g0, PSTATE_PRIV_BIT, %pstate ! Disable interrupts and disable 32-bit address masking. |
wrpr %g0, 0, %pil ! intialize %pil |
/* |
* Copy the bootinfo structure passed from the boot loader |
* to the kernel bootinfo structure. |