Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3816 → Rev 3817

/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;
170,15 → 168,12
"i" (FAST_TRAP)
: "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,14 → 181,20
* @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;
}
 
/**
/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,12 → 40,16
 
#include <arch/drivers/sgcn.h>
 
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#if defined (SUN4U)
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#endif
#elif defined (SUN4V)
#include <arch/drivers/niagara.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.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;