/kernel/trunk/genarch/include/ofw/ofw.h |
---|
32,16 → 32,16 |
/** @file |
*/ |
#ifndef __OFW_H__ |
#define __OFW_H__ |
#ifndef KERN_OFW_H_ |
#define KERN_OFW_H_ |
#include <arch/types.h> |
#define MAX_OFW_ARGS 10 |
#define MAX_OFW_ARGS 12 |
typedef unative_t ofw_arg_t; |
typedef int ihandle; |
typedef int phandle; |
typedef unsigned int ihandle; |
typedef unsigned int phandle; |
/** OpenFirmware command structure |
* |
50,20 → 50,18 |
const char *service; /**< Command name */ |
unative_t nargs; /**< Number of in arguments */ |
unative_t nret; /**< Number of out arguments */ |
ofw_arg_t args[MAX_OFW_ARGS]; /**< List of arguments */ |
ofw_arg_t args[MAX_OFW_ARGS]; /**< Buffer for in and out arguments */ |
} ofw_args_t; |
typedef void (*ofw_entry)(ofw_args_t *); |
extern int ofw(ofw_args_t *); /**< OpenFirmware Client Interface entry point. */ |
extern ofw_entry ofw; |
extern void ofw_init(void); |
extern void ofw_done(void); |
extern unative_t ofw_call(const char *service, const int nargs, const int nret, ...); |
extern ofw_arg_t ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...); |
extern void ofw_putchar(const char ch); |
extern char ofw_getchar(void); |
extern phandle ofw_find_device(const char *name); |
extern int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen); |
extern int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen); |
extern void *ofw_translate(const void *addr); |
extern void *ofw_claim(const void *addr, const int size, const int align); |
#endif |
70,4 → 68,3 |
/** @} |
*/ |
/kernel/trunk/genarch/src/ofw/memory_init.c |
---|
95,4 → 95,3 |
/** @} |
*/ |
/kernel/trunk/genarch/src/ofw/ofw.c |
---|
38,11 → 38,11 |
#include <cpu.h> |
#include <arch/types.h> |
ofw_entry ofw; |
uintptr_t ofw_cif; /**< OpenFirmware Client Interface address. */ |
phandle ofw_chosen; |
ihandle ofw_stdin; |
ihandle ofw_stdout; |
ihandle ofw_mmu; |
void ofw_init(void) |
{ |
50,20 → 50,29 |
if (ofw_chosen == -1) |
ofw_done(); |
if (ofw_get_property(ofw_chosen, "stdin", &ofw_stdin, sizeof(ofw_stdin)) <= 0) |
ofw_stdin = 0; |
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0) |
ofw_stdout = 0; |
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) |
ofw_mmu = 0; |
} |
void ofw_done(void) |
{ |
(void) ofw_call("exit", 0, 0); |
(void) ofw_call("exit", 0, 1, NULL); |
cpu_halt(); |
} |
unative_t ofw_call(const char *service, const int nargs, const int nret, ...) |
/** Perform a call to OpenFirmware client interface. |
* |
* @param service String identifying the service requested. |
* @param nargs Number of input arguments. |
* @param nret Number of output arguments. This includes the return value. |
* @param rets Buffer for output arguments or NULL. The buffer must accomodate nret - 1 items. |
* |
* @return Return value returned by the client interface. |
*/ |
ofw_arg_t ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...) |
{ |
va_list list; |
ofw_args_t args; |
73,7 → 82,7 |
args.nargs = nargs; |
args.nret = nret; |
va_start(list, nret); |
va_start(list, rets); |
for (i = 0; i < nargs; i++) |
args.args[i] = va_arg(list, ofw_arg_t); |
va_end(list); |
81,8 → 90,11 |
for (i = 0; i < nret; i++) |
args.args[i + nargs] = 0; |
ofw(&args); |
(void) ofw(&args); |
for (i = 1; i < nret; i++) |
rets[i - 1] = args.args[i + nargs]; |
return args.args[nargs]; |
} |
91,41 → 103,51 |
if (ofw_stdout == 0) |
return; |
(void) ofw_call("write", 3, 1, ofw_stdout, &ch, 1); |
(void) ofw_call("write", 3, 1, NULL, ofw_stdout, &ch, 1); |
} |
/** Read character from OFW's input. |
phandle ofw_find_device(const char *name) |
{ |
return (phandle) ofw_call("finddevice", 1, 1, NULL, name); |
} |
int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen) |
{ |
return (int) ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen); |
} |
/** Translate virtual address to physical address using OpenFirmware. |
* |
* This call is non-blocking. |
* Use this function only when OpenFirmware is in charge. |
* |
* @return 0 if no character was read, character read otherwise. |
* @param virt Virtual address. |
* @return NULL on failure or physical address on success. |
*/ |
char ofw_getchar(void) |
void *ofw_translate(const void *virt) |
{ |
char ch; |
ofw_arg_t result[4]; |
int shift; |
if (ofw_stdin == 0) |
return 0; |
if (!ofw_mmu) |
return NULL; |
if (ofw_call("read", 3, 1, ofw_stdin, &ch, 1) == 1) |
return ch; |
if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu, virt) != 0) |
return NULL; |
if (result[0] != -1) |
return NULL; |
if (sizeof(unative_t) == 8) |
shift = 32; |
else |
return 0; |
} |
shift = 0; |
phandle ofw_find_device(const char *name) |
{ |
return (phandle) ofw_call("finddevice", 1, 1, name); |
return (void *) ((result[2]<<shift)|result[3]); |
} |
int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen) |
{ |
return (int) ofw_call("getprop", 4, 1, device, name, buf, buflen); |
} |
void *ofw_claim(const void *addr, const int size, const int align) |
{ |
return (void *) ofw_call("claim", 3, 1, addr, size, align); |
return (void *) ofw_call("claim", 3, 1, NULL, addr, size, align); |
} |
/** @} |
/kernel/trunk/arch/sparc64/include/console.h |
---|
32,10 → 32,9 |
/** @file |
*/ |
#ifndef __sparc64_CONSOLE_H__ |
#define __sparc64_CONSOLE_H__ |
#ifndef KERN_sparc64_CONSOLE_H_ |
#define KERN_sparc64_CONSOLE_H_ |
extern void kofwinput(void *arg); |
extern void kkbdpoll(void *arg); |
extern void ofw_sparc64_console_init(void); |
extern void standalone_sparc64_console_init(void); |
44,4 → 43,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/stack.h |
---|
32,8 → 32,8 |
/** @file |
*/ |
#ifndef __sparc64_STACK_H__ |
#define __sparc64_STACK_H__ |
#ifndef KERN_sparc64_STACK_H_ |
#define KERN_sparc64_STACK_H_ |
#define STACK_ITEM_SIZE 8 |
54,4 → 54,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/elf.h |
---|
43,4 → 43,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/atomic.h |
---|
101,4 → 101,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/asm.h |
---|
32,8 → 32,8 |
/** @file |
*/ |
#ifndef __sparc64_ASM_H__ |
#define __sparc64_ASM_H__ |
#ifndef KERN_sparc64_ASM_H_ |
#define KERN_sparc64_ASM_H_ |
#include <typedefs.h> |
#include <arch/types.h> |
304,8 → 304,6 |
__asm__ volatile ("stxa %0, [%1] %2\n" : : "r" (v), "r" (va), "i" (asi) : "memory"); |
} |
void cpu_halt(void); |
void cpu_sleep(void); |
void asm_delay_loop(uint32_t t); |
314,4 → 312,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/trap/interrupt.h |
---|
78,4 → 78,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/register.h |
---|
32,9 → 32,14 |
/** @file |
*/ |
#ifndef __sparc64_REGISTER_H__ |
#define __sparc64_REGISTER_H__ |
#ifndef KERN_sparc64_REGISTER_H_ |
#define KERN_sparc64_REGISTER_H_ |
#ifdef __ASM__ |
#define PSTATE_IE_BIT 2 |
#define PSTATE_AM_BIT 8 |
#else |
#include <arch/types.h> |
/** Version Register. */ |
106,6 → 111,7 |
#endif |
#endif |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/barrier.h |
---|
71,4 → 71,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/drivers/i8042.h |
---|
32,8 → 32,8 |
/** @file |
*/ |
#ifndef __sparc64_I8042_H__ |
#define __sparc64_I8042_H__ |
#ifndef KERN_sparc64_I8042_H_ |
#define KERN_sparc64_I8042_H_ |
#include <arch/types.h> |
73,4 → 73,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/include/drivers/fb.h |
---|
32,8 → 32,8 |
/** @file |
*/ |
#ifndef __sparc64_FB_H__ |
#define __sparc64_FB_H__ |
#ifndef KERN_sparc64_FB_H_ |
#define KERN_sparc64_FB_H_ |
#define FB_PHYS_ADDRESS 0x1c901000000ULL |
46,4 → 46,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/src/asm.S |
---|
26,6 → 26,9 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/stack.h> |
#include <arch/register.h> |
.text |
.global memcpy |
35,6 → 38,7 |
.global memcpy_to_uspace_failover_address |
.global memsetb |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
51,3 → 55,20 |
b _memsetb |
nop |
.global ofw |
ofw: |
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
set ofw_cif, %l0 |
ldx [%l0], %l0 |
rdpr %pstate, %l1 |
and %l1, ~PSTATE_AM_BIT, %l2 |
wrpr %l2, 0, %pstate |
jmpl %l0, %o7 |
mov %i0, %o0 |
wrpr %l1, 0, %pstate |
ret |
restore %o0, 0, %o0 |
/kernel/trunk/arch/sparc64/src/console.c |
---|
51,20 → 51,12 |
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */ |
static void ofw_sparc64_putchar(chardev_t *d, const char ch); |
static char ofw_sparc64_getchar(chardev_t *d); |
static void ofw_sparc64_suspend(chardev_t *d); |
static void ofw_sparc64_resume(chardev_t *d); |
mutex_t canwork; |
static volatile int ofw_console_active; |
static chardev_t ofw_sparc64_console; |
static chardev_operations_t ofw_sparc64_console_ops = { |
.write = ofw_sparc64_putchar, |
.read = ofw_sparc64_getchar, |
.resume = ofw_sparc64_resume, |
.suspend = ofw_sparc64_suspend |
}; |
/** Initialize kernel console to use OpenFirmware services. */ |
71,9 → 63,8 |
void ofw_sparc64_console_init(void) |
{ |
chardev_initialize("ofw_sparc64_console", &ofw_sparc64_console, &ofw_sparc64_console_ops); |
stdin = &ofw_sparc64_console; |
stdin = NULL; |
stdout = &ofw_sparc64_console; |
mutex_initialize(&canwork); |
ofw_console_active = 1; |
} |
94,83 → 85,11 |
*/ |
void ofw_sparc64_putchar(chardev_t *d, const char ch) |
{ |
pstate_reg_t pstate; |
/* |
* 32-bit OpenFirmware depends on PSTATE.AM bit set. |
*/ |
pstate.value = pstate_read(); |
pstate.am = true; |
pstate_write(pstate.value); |
if (ch == '\n') |
ofw_putchar('\r'); |
ofw_putchar(ch); |
pstate.am = false; |
pstate_write(pstate.value); |
} |
/** Read one character using OpenFirmware. |
* |
* The call is non-blocking. |
* |
* @param d Character device (ignored). |
* @return Character read or zero if no character was read. |
*/ |
char ofw_sparc64_getchar(chardev_t *d) |
{ |
char ch; |
pstate_reg_t pstate; |
/* |
* 32-bit OpenFirmware depends on PSTATE.AM bit set. |
*/ |
pstate.value = pstate_read(); |
pstate.am = true; |
pstate_write(pstate.value); |
ch = ofw_getchar(); |
pstate.am = false; |
pstate_write(pstate.value); |
return ch; |
} |
void ofw_sparc64_suspend(chardev_t *d) |
{ |
mutex_lock(&canwork); |
} |
void ofw_sparc64_resume(chardev_t *d) |
{ |
mutex_unlock(&canwork); |
} |
/** Kernel thread for pushing characters read from OFW to input buffer. |
* |
* @param arg Ignored. |
*/ |
void kofwinput(void *arg) |
{ |
while (ofw_console_active) { |
char ch = 0; |
mutex_lock(&canwork); |
mutex_unlock(&canwork); |
ch = ofw_sparc64_getchar(NULL); |
if (ch) { |
if (ch == '\r') |
ch = '\n'; |
chardev_push_character(&ofw_sparc64_console, ch); |
} |
thread_usleep(KEYBOARD_POLL_PAUSE); |
} |
} |
/** Kernel thread for polling keyboard. |
* |
* @param arg Ignored. |
/kernel/trunk/arch/sparc64/src/proc/scheduler.c |
---|
81,4 → 81,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/src/sparc64.c |
---|
40,10 → 40,15 |
#include <proc/thread.h> |
#include <console/console.h> |
#include <print.h> |
#include <genarch/ofw/ofw.h> |
#include <arch/asm.h> |
#include <arch/register.h> |
void arch_pre_mm_init(void) |
{ |
interrupts_disable(); |
ofw_sparc64_console_init(); |
trap_init(); |
tick_init(); |
} |
62,14 → 67,6 |
thread_t *t; |
/* |
* Create thread that reads characters from OFW's input. |
*/ |
t = thread_create(kofwinput, NULL, TASK, 0, "kofwinput"); |
if (!t) |
panic("cannot create kofwinput\n"); |
thread_ready(t); |
/* |
* Create thread that polls keyboard. |
*/ |
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll"); |
/kernel/trunk/arch/sparc64/src/mm/frame.c |
---|
53,4 → 53,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/src/drivers/i8042.c |
---|
47,4 → 47,3 |
/** @} |
*/ |
/kernel/trunk/arch/sparc64/src/start.S |
---|
27,6 → 27,7 |
# |
#include <arch/boot/boot.h> |
#include <arch/register.h> |
.register %g2, #scratch |
.register %g3, #scratch |
37,8 → 38,6 |
/* |
* Here is where the kernel is passed control. |
* The code must be position independent until |
* the kernel relocates itself to its VMA. |
*/ |
.global kernel_image_start |
45,8 → 44,12 |
kernel_image_start: |
flushw ! flush all but the active register window |
set ofw, %l0 |
rdpr %pstate, %l0 |
and %l0, ~PSTATE_AM_BIT, %l0 |
wrpr %l0, 0, %pstate |
set ofw_cif, %l0 |
call ofw_init |
stx %o4, [%l0] |