/branches/sparc/kernel/generic/src/main/kinit.c |
---|
157,6 → 157,7 |
interrupts_enable(); |
#if defined (SUN4U) |
/* |
* Create user tasks, load RAM disk images. |
*/ |
214,6 → 215,7 |
} |
} |
#endif /* CONFIG_KCONSOLE */ |
#endif |
} |
/** @} |
/branches/sparc/kernel/arch/sparc64/include/sun4v/hypercall.h |
---|
139,7 → 139,8 |
__hypercall_fast(p1, p2, p3, p4, p5, function_number) |
/** |
* Performs a fast hypervisor API call which can returns a value. |
* Performs a fast hypervisor API call which returns no value except for the |
* error status. |
* |
* @param p1 the 1st argument of the hypervisor API call |
* @param p2 the 2nd argument of the hypervisor API call |
147,14 → 148,11 |
* @param p4 the 4th argument of the hypervisor API call |
* @param p5 the 5th argument of the hypervisor API call |
* @param function_number function number of the call |
* @param ret1 pointer to an address where the return value |
* of the hypercall should be saved, or NULL |
* @return error status |
*/ |
static inline uint64_t |
__hypercall_fast_ret1(const uint64_t p1, const uint64_t p2, const uint64_t p3, |
const uint64_t p4, const uint64_t p5, const uint64_t function_number, |
uint64_t * const ret1) |
__hypercall_fast(const uint64_t p1, const uint64_t p2, const uint64_t p3, |
const uint64_t p4, const uint64_t p5, const uint64_t function_number) |
{ |
register uint64_t a6 asm("o5") = function_number; |
register uint64_t a1 asm("o0") = p1; |
171,14 → 169,11 |
: "memory" |
); |
if (ret1 != NULL) |
*ret1 = a2; |
return a1; |
} |
/** |
* Performs a fast hypervisor API call which return no value except for the |
* error status. |
* Performs a fast hypervisor API call which can return a value. |
* |
* @param p1 the 1st argument of the hypervisor API call |
* @param p2 the 2nd argument of the hypervisor API call |
186,15 → 181,21 |
* @param p4 the 4th argument of the hypervisor API call |
* @param p5 the 5th argument of the hypervisor API call |
* @param function_number function number of the call |
* @param ret1 pointer to an address where the return value |
* of the hypercall should be saved, or NULL |
* @return error status |
*/ |
static inline uint64_t |
__hypercall_fast(const uint64_t p1, const uint64_t p2, const uint64_t p3, |
const uint64_t p4, const uint64_t p5, const uint64_t function_number) |
__hypercall_fast_ret1(const uint64_t p1, const uint64_t p2, const uint64_t p3, |
const uint64_t p4, const uint64_t p5, const uint64_t function_number, |
uint64_t * const ret1) |
{ |
return __hypercall_fast_ret1(p1, p2, p3, p4, p5, function_number, |
NULL); |
uint64_t errno = __hypercall_fast(p1, p2, p3, p4, p5, function_number); |
if (ret1 != NULL) { |
asm volatile ("mov %%o1, %0\n" : "=r" (*ret1)); |
} |
return errno; |
} |
/** |
* Performs a hyperfast hypervisor API call. |
/branches/sparc/kernel/arch/sparc64/include/drivers/kbd.h |
---|
42,7 → 42,8 |
KBD_UNKNOWN, |
KBD_Z8530, |
KBD_NS16550, |
KBD_SGCN |
KBD_SGCN, /* Serengeti console keyboard */ |
KBD_SUN4V /* Niagara hypervisor's virtual standard input */ |
} kbd_type_t; |
extern kbd_type_t kbd_type; |
/branches/sparc/kernel/arch/sparc64/include/drivers/niagara.h |
---|
38,6 → 38,7 |
void niagara_grab(void); |
void niagara_release(void); |
void niagara_init(void); |
void niagara_poll(void); |
#endif |
/branches/sparc/kernel/arch/sparc64/Makefile.inc |
---|
110,6 → 110,7 |
arch/$(ARCH)/src/$(USARCH)/asm.S \ |
arch/$(ARCH)/src/$(USARCH)/sparc64.c \ |
arch/$(ARCH)/src/mm/$(USARCH)/tlb.c \ |
arch/$(ARCH)/src/mm/$(USARCH)/as.c \ |
arch/$(ARCH)/src/cpu/$(USARCH)/cpu.c |
# specific to machine type |
122,7 → 123,6 |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/cache.S \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
/branches/sparc/kernel/arch/sparc64/src/sun4v/sparc64.c |
---|
50,8 → 50,6 |
#include <ddi/irq.h> |
#include <print.h> |
#include <arch/drivers/niagara.h> |
bootinfo_t bootinfo; |
/** Perform sparc64 specific initialization before main_bsp() is called. */ |
89,10 → 87,7 |
irq_init(1 << 11, 128); |
} |
/* |
* Initialize Niagara input/output driver. |
*/ |
niagara_init(); |
standalone_sparc64_console_init(); |
} |
void arch_post_cpu_init(void) |
/branches/sparc/kernel/arch/sparc64/src/console.c |
---|
40,6 → 40,7 |
#include <arch/drivers/sgcn.h> |
#if defined (SUN4U) |
#ifdef CONFIG_Z8530 |
#include <genarch/kbd/z8530.h> |
#endif |
46,6 → 47,9 |
#ifdef CONFIG_NS16550 |
#include <genarch/kbd/ns16550.h> |
#endif |
#elif defined (SUN4V) |
#include <arch/drivers/niagara.h> |
#endif |
#include <console/chardev.h> |
#include <console/console.h> |
61,6 → 65,8 |
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */ |
#if defined (SUN4U) |
/** |
* Initialize kernel console to use framebuffer and keyboard directly. |
* Called on UltraSPARC machines with standard keyboard and framebuffer. |
104,6 → 110,8 |
sgcn_init(); |
} |
#endif |
/** |
* Initialize input/output. Auto-detects the type of machine |
* and calls the appropriate I/O init routine. |
110,6 → 118,7 |
*/ |
void standalone_sparc64_console_init(void) |
{ |
#if defined (SUN4U) |
ofw_tree_node_t *aliases; |
ofw_tree_property_t *prop; |
125,6 → 134,9 |
} else { |
serengeti_init(); |
} |
#elif defined (SUN4V) |
niagara_init(); |
#endif |
} |
166,6 → 178,10 |
if (kbd_type == KBD_SGCN) |
sgcn_poll(); |
#endif |
#ifdef SUN4V |
if (kbd_type == KBD_SUN4V) |
niagara_poll(); |
#endif |
thread_usleep(KEYBOARD_POLL_PAUSE); |
} |
} |
/branches/sparc/kernel/arch/sparc64/src/mm/as.c |
---|
File deleted |
/branches/sparc/kernel/arch/sparc64/src/mm/sun4v/as.c |
---|
0,0 → 1,229 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* Copyright (c) 2009 Pavel Rimsky |
* 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 sparc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/as.h> |
#include <arch/mm/pagesize.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <genarch/mm/page_ht.h> |
#include <genarch/mm/asid_fifo.h> |
#include <debug.h> |
#include <config.h> |
#ifdef CONFIG_TSB |
#include <arch/mm/tsb.h> |
#include <arch/memstr.h> |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <bitops.h> |
#include <macros.h> |
#endif /* CONFIG_TSB */ |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
as_operations = &as_ht_operations; |
asid_fifo_init(); |
} |
} |
int as_constructor_arch(as_t *as, int flags) |
{ |
#ifdef CONFIG_TSB |
/* |
* The order must be calculated with respect to the emulated |
* 16K page size. |
*/ |
int order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH); |
uintptr_t tsb = (uintptr_t) frame_alloc(order, flags | FRAME_KA); |
if (!tsb) |
return -1; |
as->arch.itsb = (tsb_entry_t *) tsb; |
as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT * |
sizeof(tsb_entry_t)); |
memsetb(as->arch.itsb, |
(ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0); |
#endif |
return 0; |
} |
int as_destructor_arch(as_t *as) |
{ |
#ifdef CONFIG_TSB |
/* |
* The count must be calculated with respect to the emualted 16K page |
* size. |
*/ |
count_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH; |
frame_free(KA2PA((uintptr_t) as->arch.itsb)); |
return cnt; |
#else |
return 0; |
#endif |
} |
int as_create_arch(as_t *as, int flags) |
{ |
#ifdef CONFIG_TSB |
tsb_invalidate(as, 0, (count_t) -1); |
#endif |
return 0; |
} |
/** Perform sparc64-specific tasks when an address space becomes active on the |
* processor. |
* |
* Install ASID and map TSBs. |
* |
* @param as Address space. |
*/ |
void as_install_arch(as_t *as) |
{ |
#if 0 |
tlb_context_reg_t ctx; |
/* |
* Note that we don't and may not lock the address space. That's ok |
* since we only read members that are currently read-only. |
* |
* Moreover, the as->asid is protected by asidlock, which is being held. |
*/ |
/* |
* Write ASID to secondary context register. The primary context |
* register has to be set from TL>0 so it will be filled from the |
* secondary context register from the TL=1 code just before switch to |
* userspace. |
*/ |
ctx.v = 0; |
ctx.context = as->asid; |
mmu_secondary_context_write(ctx.v); |
#ifdef CONFIG_TSB |
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
ASSERT(as->arch.itsb && as->arch.dtsb); |
uintptr_t tsb = (uintptr_t) as->arch.itsb; |
if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
/* |
* TSBs were allocated from memory not covered |
* by the locked 4M kernel DTLB entry. We need |
* to map both TSBs explicitly. |
*/ |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb); |
dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true); |
} |
/* |
* Setup TSB Base registers. |
*/ |
tsb_base_reg_t tsb_base; |
tsb_base.value = 0; |
tsb_base.size = TSB_SIZE; |
tsb_base.split = 0; |
tsb_base.base = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH; |
itsb_base_write(tsb_base.value); |
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH; |
dtsb_base_write(tsb_base.value); |
#if defined (US3) |
/* |
* Clear the extension registers. |
* In HelenOS, primary and secondary context registers contain |
* equal values and kernel misses (context 0, ie. the nucleus context) |
* are excluded from the TSB miss handler, so it makes no sense |
* to have separate TSBs for primary, secondary and nucleus contexts. |
* Clearing the extension registers will ensure that the value of the |
* TSB Base register will be used as an address of TSB, making the code |
* compatible with the US port. |
*/ |
itsb_primary_extension_write(0); |
itsb_nucleus_extension_write(0); |
dtsb_primary_extension_write(0); |
dtsb_secondary_extension_write(0); |
dtsb_nucleus_extension_write(0); |
#endif |
#endif |
#endif |
} |
/** Perform sparc64-specific tasks when an address space is removed from the |
* processor. |
* |
* Demap TSBs. |
* |
* @param as Address space. |
*/ |
void as_deinstall_arch(as_t *as) |
{ |
/* |
* Note that we don't and may not lock the address space. That's ok |
* since we only read members that are currently read-only. |
* |
* Moreover, the as->asid is protected by asidlock, which is being held. |
*/ |
#ifdef CONFIG_TSB |
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
ASSERT(as->arch.itsb && as->arch.dtsb); |
uintptr_t tsb = (uintptr_t) as->arch.itsb; |
if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
/* |
* TSBs were allocated from memory not covered |
* by the locked 4M kernel DTLB entry. We need |
* to demap the entry installed by as_install_arch(). |
*/ |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb); |
} |
#endif |
} |
/** @} |
*/ |
/branches/sparc/kernel/arch/sparc64/src/mm/sun4u/as.c |
---|
0,0 → 1,226 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* 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 sparc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/as.h> |
#include <arch/mm/pagesize.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <arch/mm/sun4u/tlb.h> |
#include <genarch/mm/page_ht.h> |
#include <genarch/mm/asid_fifo.h> |
#include <debug.h> |
#include <config.h> |
#ifdef CONFIG_TSB |
#include <arch/mm/tsb.h> |
#include <arch/memstr.h> |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <bitops.h> |
#include <macros.h> |
#endif /* CONFIG_TSB */ |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
as_operations = &as_ht_operations; |
asid_fifo_init(); |
} |
} |
int as_constructor_arch(as_t *as, int flags) |
{ |
#ifdef CONFIG_TSB |
/* |
* The order must be calculated with respect to the emulated |
* 16K page size. |
*/ |
int order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH); |
uintptr_t tsb = (uintptr_t) frame_alloc(order, flags | FRAME_KA); |
if (!tsb) |
return -1; |
as->arch.itsb = (tsb_entry_t *) tsb; |
as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT * |
sizeof(tsb_entry_t)); |
memsetb(as->arch.itsb, |
(ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0); |
#endif |
return 0; |
} |
int as_destructor_arch(as_t *as) |
{ |
#ifdef CONFIG_TSB |
/* |
* The count must be calculated with respect to the emualted 16K page |
* size. |
*/ |
count_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * |
sizeof(tsb_entry_t)) >> FRAME_WIDTH; |
frame_free(KA2PA((uintptr_t) as->arch.itsb)); |
return cnt; |
#else |
return 0; |
#endif |
} |
int as_create_arch(as_t *as, int flags) |
{ |
#ifdef CONFIG_TSB |
tsb_invalidate(as, 0, (count_t) -1); |
#endif |
return 0; |
} |
/** Perform sparc64-specific tasks when an address space becomes active on the |
* processor. |
* |
* Install ASID and map TSBs. |
* |
* @param as Address space. |
*/ |
void as_install_arch(as_t *as) |
{ |
tlb_context_reg_t ctx; |
/* |
* Note that we don't and may not lock the address space. That's ok |
* since we only read members that are currently read-only. |
* |
* Moreover, the as->asid is protected by asidlock, which is being held. |
*/ |
/* |
* Write ASID to secondary context register. The primary context |
* register has to be set from TL>0 so it will be filled from the |
* secondary context register from the TL=1 code just before switch to |
* userspace. |
*/ |
ctx.v = 0; |
ctx.context = as->asid; |
mmu_secondary_context_write(ctx.v); |
#ifdef CONFIG_TSB |
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
ASSERT(as->arch.itsb && as->arch.dtsb); |
uintptr_t tsb = (uintptr_t) as->arch.itsb; |
if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
/* |
* TSBs were allocated from memory not covered |
* by the locked 4M kernel DTLB entry. We need |
* to map both TSBs explicitly. |
*/ |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb); |
dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true); |
} |
/* |
* Setup TSB Base registers. |
*/ |
tsb_base_reg_t tsb_base; |
tsb_base.value = 0; |
tsb_base.size = TSB_SIZE; |
tsb_base.split = 0; |
tsb_base.base = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH; |
itsb_base_write(tsb_base.value); |
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH; |
dtsb_base_write(tsb_base.value); |
#if defined (US3) |
/* |
* Clear the extension registers. |
* In HelenOS, primary and secondary context registers contain |
* equal values and kernel misses (context 0, ie. the nucleus context) |
* are excluded from the TSB miss handler, so it makes no sense |
* to have separate TSBs for primary, secondary and nucleus contexts. |
* Clearing the extension registers will ensure that the value of the |
* TSB Base register will be used as an address of TSB, making the code |
* compatible with the US port. |
*/ |
itsb_primary_extension_write(0); |
itsb_nucleus_extension_write(0); |
dtsb_primary_extension_write(0); |
dtsb_secondary_extension_write(0); |
dtsb_nucleus_extension_write(0); |
#endif |
#endif |
} |
/** Perform sparc64-specific tasks when an address space is removed from the |
* processor. |
* |
* Demap TSBs. |
* |
* @param as Address space. |
*/ |
void as_deinstall_arch(as_t *as) |
{ |
/* |
* Note that we don't and may not lock the address space. That's ok |
* since we only read members that are currently read-only. |
* |
* Moreover, the as->asid is protected by asidlock, which is being held. |
*/ |
#ifdef CONFIG_TSB |
uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
ASSERT(as->arch.itsb && as->arch.dtsb); |
uintptr_t tsb = (uintptr_t) as->arch.itsb; |
if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
/* |
* TSBs were allocated from memory not covered |
* by the locked 4M kernel DTLB entry. We need |
* to demap the entry installed by as_install_arch(). |
*/ |
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb); |
} |
#endif |
} |
/** @} |
*/ |
/branches/sparc/kernel/arch/sparc64/src/drivers/niagara.c |
---|
37,19 → 37,28 |
#include <arch/drivers/niagara.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <arch/drivers/kbd.h> |
#include <arch/sun4v/hypercall.h> |
/* functions referenced from definitions of I/O operations structures */ |
static void niagara_putchar(chardev_t *, const char); |
static void niagara_noop(chardev_t *); |
static char niagara_read(chardev_t *); |
/** character device operations */ |
static chardev_operations_t niagara_ops = { |
.write = niagara_putchar |
.write = niagara_putchar, |
.suspend = niagara_noop, |
.resume = niagara_noop, |
.read = niagara_read |
}; |
/** Niagara character device */ |
chardev_t niagara_io; |
/** defined in drivers/kbd.c */ |
extern kbd_type_t kbd_type; |
/** Writes a single character to the standard output. */ |
static void niagara_putchar(struct chardev * cd, const char c) |
{ |
58,7 → 67,6 |
__hypercall_fast1(CONS_PUTCHAR, '\r'); |
} |
/** |
* Grabs the input for kernel. |
*/ |
74,11 → 82,45 |
} |
/** |
* Default suspend/resume operation for the input device. |
*/ |
static void niagara_noop(chardev_t *d) |
{ |
} |
/** |
* Called when actively reading the character. Not implemented yet. |
*/ |
static char niagara_read(chardev_t *d) |
{ |
return (char) 0; |
} |
/** |
* Function regularly called by the keyboard polling thread. Asks the |
* hypervisor whether there is any unread character. If so, it picks it up |
* and sends it to the upper layers of HelenOS. |
*/ |
void niagara_poll(void) |
{ |
uint64_t c = 50; |
if (__hypercall_fast_ret1(0, 0, 0, 0, 0, CONS_GETCHAR, &c) == EOK) { |
chardev_push_character(&niagara_io, c); |
if (c == '\r') |
chardev_push_character(&niagara_io, '\n'); |
} |
} |
/** |
* Initializes the input/output subsystem so that the Niagara standard |
* input/output is used. |
*/ |
void niagara_init(void) |
{ |
kbd_type = KBD_SUN4V; |
chardev_initialize("niagara_io", &niagara_io, &niagara_ops); |
stdin = &niagara_io; |
stdout = &niagara_io; |