Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3887 → Rev 3888

/tags/0.4.0/kernel/arch/sparc64/Makefile.inc
0,0 → 1,144
#
# Copyright (c) 2005 Martin Decky
# 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.
#
 
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf64-sparc
BFD_ARCH = sparc
BFD = binary
TARGET = sparc64-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64
 
GCC_CFLAGS += -m64 -mcpu=ultrasparc
SUNCC_CFLAGS += -m64 -xarch=sparc -xregs=appl,no%float
 
LFLAGS += -no-check-sections -N
 
DEFS += -D__64_BITS__
 
## Own configuration directives
#
 
## Compile with page hash table support.
#
 
CONFIG_PAGE_HT = y
DEFS += -DCONFIG_PAGE_HT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Compile with support for framebuffer.
#
 
ifeq ($(MACHINE),us)
CONFIG_FB = y
endif
 
## Compile with support for Sun keyboard.
#
 
CONFIG_SUN_KBD = y
 
## Compile with support for OpenFirmware device tree.
#
 
CONFIG_OFW_TREE = y
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
 
ifeq ($(CONFIG_SGCN),y)
DEFS += -DCONFIG_SGCN
endif
 
ifeq ($(MACHINE),us)
DEFS += -DUS
endif
 
ifeq ($(MACHINE),us3)
DEFS += -DUS3
endif
 
ARCH_SOURCES = \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/console.c \
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 \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/sparc64.c \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/trap/mmu.S \
arch/$(ARCH)/src/trap/trap_table.S \
arch/$(ARCH)/src/trap/trap.c \
arch/$(ARCH)/src/trap/exception.c \
arch/$(ARCH)/src/trap/interrupt.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/tick.c \
arch/$(ARCH)/src/drivers/kbd.c \
arch/$(ARCH)/src/drivers/sgcn.c \
arch/$(ARCH)/src/drivers/pci.c
 
ifeq ($(CONFIG_FB),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/drivers/scr.c
endif
 
ifeq ($(CONFIG_SMP),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/smp/smp.c
endif
 
ifeq ($(CONFIG_TSB),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/mm/tsb.c
endif
 
ifdef CONFIG_Z8530
ARCH_SOURCES += \
arch/$(ARCH)/src/drivers/fhc.c
endif
/tags/0.4.0/kernel/arch/sparc64/src/console.c
0,0 → 1,234
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch/console.h>
#include <arch/types.h>
 
#include <arch/drivers/scr.h>
#include <arch/drivers/kbd.h>
 
#include <arch/drivers/sgcn.h>
 
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#endif
 
#include <console/chardev.h>
#include <console/console.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <proc/thread.h>
#include <arch/mm/tlb.h>
#include <genarch/ofw/ofw_tree.h>
#include <arch.h>
#include <panic.h>
#include <func.h>
#include <print.h>
 
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */
 
/**
* Initialize kernel console to use framebuffer and keyboard directly.
* Called on UltraSPARC machines with standard keyboard and framebuffer.
*
* @param aliases the "/aliases" OBP node
*/
static void standard_console_init(ofw_tree_node_t *aliases)
{
#ifdef CONFIG_FB
stdin = NULL;
 
ofw_tree_property_t *prop;
ofw_tree_node_t *screen;
ofw_tree_node_t *keyboard;
prop = ofw_tree_getprop(aliases, "screen");
if (!prop)
panic("Cannot find property 'screen'.");
if (!prop->value)
panic("Cannot find screen alias.");
screen = ofw_tree_lookup(prop->value);
if (!screen)
panic("Cannot find %s.", prop->value);
 
scr_init(screen);
 
prop = ofw_tree_getprop(aliases, "keyboard");
if (!prop)
panic("Cannot find property 'keyboard'.");
if (!prop->value)
panic("Cannot find keyboard alias.");
keyboard = ofw_tree_lookup(prop->value);
if (!keyboard)
panic("Cannot find %s.", prop->value);
 
kbd_init(keyboard);
#else
panic("Standard console requires FB, "
"but the kernel is not compiled with FB support.");
#endif
}
 
/** Initilize I/O on the Serengeti machine. */
static void serengeti_init(void)
{
sgcn_init();
}
 
/**
* Initialize input/output. Auto-detects the type of machine
* and calls the appropriate I/O init routine.
*/
void standalone_sparc64_console_init(void)
{
ofw_tree_node_t *aliases;
ofw_tree_property_t *prop;
aliases = ofw_tree_lookup("/aliases");
if (!aliases)
panic("Cannot find '/aliases'.");
/* "def-cn" = "default console" */
prop = ofw_tree_getprop(aliases, "def-cn");
if ((!prop) || (!prop->value) || (strcmp(prop->value, "/sgcn") != 0)) {
standard_console_init(aliases);
} else {
serengeti_init();
}
}
 
 
/** Kernel thread for polling keyboard.
*
* @param arg Ignored.
*/
void kkbdpoll(void *arg)
{
thread_detach(THREAD);
 
#ifdef CONFIG_Z8530
if (kbd_type == KBD_Z8530) {
/*
* The z8530 driver is interrupt-driven.
*/
return;
}
#endif
 
#ifdef CONFIG_NS16550
#ifdef CONFIG_NS16550_INTERRUPT_DRIVEN
if (kbd_type == KBD_NS16550) {
/*
* The ns16550 driver is interrupt-driven.
*/
return;
}
#endif
#endif
while (1) {
#ifdef CONFIG_NS16550
#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN
if (kbd_type == KBD_NS16550)
ns16550_poll();
#endif
#endif
#ifdef CONFIG_SGCN
if (kbd_type == KBD_SGCN)
sgcn_poll();
#endif
thread_usleep(KEYBOARD_POLL_PAUSE);
}
}
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
#ifdef CONFIG_FB
scr_redraw();
#endif
switch (kbd_type) {
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_grab();
break;
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_grab();
break;
#endif
#ifdef CONFIG_SGCN
case KBD_SGCN:
sgcn_grab();
break;
#endif
default:
break;
}
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
switch (kbd_type) {
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_release();
break;
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_release();
break;
#endif
#ifdef CONFIG_SGCN
case KBD_SGCN:
sgcn_release();
break;
#endif
default:
break;
}
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/drivers/sgcn.c
0,0 → 1,451
/*
* Copyright (c) 2008 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 sparc64
* @{
*/
/**
* @file
* @brief SGCN driver.
*/
 
#include <arch/drivers/sgcn.h>
#include <arch/drivers/kbd.h>
#include <genarch/ofw/ofw_tree.h>
#include <debug.h>
#include <func.h>
#include <print.h>
#include <mm/page.h>
#include <ipc/irq.h>
#include <ddi/ddi.h>
#include <ddi/device.h>
#include <console/chardev.h>
#include <console/console.h>
#include <ddi/device.h>
#include <sysinfo/sysinfo.h>
#include <synch/spinlock.h>
 
/*
* Physical address at which the SBBC starts. This value has been obtained
* by inspecting (using Simics) memory accesses made by OBP. It is valid
* for the Simics-simulated Serengeti machine. The author of this code is
* not sure whether this value is valid generally.
*/
#define SBBC_START 0x63000000000
 
/* offset of SRAM within the SBBC memory */
#define SBBC_SRAM_OFFSET 0x900000
 
/* size (in bytes) of the physical memory area which will be mapped */
#define MAPPED_AREA_SIZE (128 * 1024)
 
/* magic string contained at the beginning of SRAM */
#define SRAM_TOC_MAGIC "TOCSRAM"
 
/*
* Key into the SRAM table of contents which identifies the entry
* describing the OBP console buffer. It is worth mentioning
* that the OBP console buffer is not the only console buffer
* which can be used. It is, however, used because when the kernel
* is running, the OBP buffer is not used by OBP any more but OBP
* has already made neccessary arangements so that the output will
* be read from the OBP buffer and input will go to the OBP buffer.
* Therefore HelenOS needs to make no such arrangements any more.
*/
#define CONSOLE_KEY "OBPCONS"
 
/* magic string contained at the beginning of the console buffer */
#define SGCN_BUFFER_MAGIC "CON"
 
/**
* The driver is polling based, but in order to notify the userspace
* of a key being pressed, we need to supply the interface with some
* interrupt number. The interrupt number can be arbitrary as it it
* will never be used for identifying HW interrupts, but only in
* notifying the userspace.
*/
#define FICTIONAL_INR 1
 
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the SRAM beginning.
*/
#define SRAM(type, offset) ((type *) (sram_begin + (offset)))
 
/* Returns a pointer to the SRAM table of contents. */
#define SRAM_TOC (SRAM(iosram_toc_t, 0))
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sgcn_buffer_begin + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
 
/** defined in drivers/kbd.c */
extern kbd_type_t kbd_type;
 
/** starting address of SRAM, will be set by the init_sram_begin function */
static uintptr_t sram_begin;
 
/**
* starting address of the SGCN buffer, will be set by the
* init_sgcn_buffer_begin function
*/
static uintptr_t sgcn_buffer_begin;
 
/**
* SGCN IRQ structure. So far used only for notifying the userspace of the
* key being pressed, not for kernel being informed about keyboard interrupts.
*/
static irq_t sgcn_irq;
 
// TODO think of a way how to synchronize accesses to SGCN buffer between the kernel and the userspace
 
/*
* Ensures that writing to the buffer and consequent update of the write pointer
* are together one atomic operation.
*/
SPINLOCK_INITIALIZE(sgcn_output_lock);
 
/*
* Prevents the input buffer read/write pointers from getting to inconsistent
* state.
*/
SPINLOCK_INITIALIZE(sgcn_input_lock);
 
 
/* functions referenced from definitions of I/O operations structures */
static void sgcn_noop(chardev_t *);
static void sgcn_putchar(chardev_t *, const char, bool);
static char sgcn_key_read(chardev_t *);
 
/** character device operations */
static chardev_operations_t sgcn_ops = {
.suspend = sgcn_noop,
.resume = sgcn_noop,
.read = sgcn_key_read,
.write = sgcn_putchar
};
 
/** SGCN character device */
chardev_t sgcn_io;
 
/**
* Registers the physical area of the SRAM so that the userspace SGCN
* driver can map it. Moreover, it sets some sysinfo values (SRAM address
* and SRAM size).
*/
static void register_sram_parea(uintptr_t sram_begin_physical)
{
static parea_t sram_parea;
sram_parea.pbase = sram_begin_physical;
sram_parea.vbase = (uintptr_t) sram_begin;
sram_parea.frames = MAPPED_AREA_SIZE / FRAME_SIZE;
sram_parea.cacheable = false;
ddi_parea_register(&sram_parea);
sysinfo_set_item_val("sram.area.size", NULL, MAPPED_AREA_SIZE);
sysinfo_set_item_val("sram.address.physical", NULL,
sram_begin_physical);
}
 
/**
* Initializes the starting address of SRAM.
*
* The SRAM starts 0x900000 + C bytes behind the SBBC start in the
* physical memory, where C is the value read from the "iosram-toc"
* property of the "/chosen" OBP node. The sram_begin variable will
* be set to the virtual address which maps to the SRAM physical
* address.
*
* It also registers the physical area of SRAM and sets some sysinfo
* values (SRAM address and SRAM size).
*/
static void init_sram_begin(void)
{
ofw_tree_node_t *chosen;
ofw_tree_property_t *iosram_toc;
uintptr_t sram_begin_physical;
 
chosen = ofw_tree_lookup("/chosen");
if (!chosen)
panic("Cannot find '/chosen'.");
 
iosram_toc = ofw_tree_getprop(chosen, "iosram-toc");
if (!iosram_toc)
panic("Cannot find property 'iosram-toc'.");
if (!iosram_toc->value)
panic("Cannot find SRAM TOC.");
 
sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
+ *((uint32_t *) iosram_toc->value);
sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
register_sram_parea(sram_begin_physical);
}
 
/**
* Initializes the starting address of the SGCN buffer.
*
* The offset of the SGCN buffer within SRAM is obtained from the
* SRAM table of contents. The table of contents contains
* information about several buffers, among which there is an OBP
* console buffer - this one will be used as the SGCN buffer.
*
* This function also writes the offset of the SGCN buffer within SRAM
* under the sram.buffer.offset sysinfo key.
*/
static void sgcn_buffer_begin_init(void)
{
init_sram_begin();
ASSERT(strcmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
/* lookup TOC entry with the correct key */
uint32_t i;
for (i = 0; i < MAX_TOC_ENTRIES; i++) {
if (strcmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
break;
}
ASSERT(i < MAX_TOC_ENTRIES);
sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset;
sysinfo_set_item_val("sram.buffer.offset", NULL,
SRAM_TOC->keys[i].offset);
}
 
/**
* Default suspend/resume operation for the input device.
*/
static void sgcn_noop(chardev_t *d)
{
}
 
/**
* Writes a single character to the SGCN (circular) output buffer
* and updates the output write pointer so that SGCN gets to know
* that the character has been written.
*/
static void sgcn_do_putchar(const char c)
{
uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
uint32_t end = SGCN_BUFFER_HEADER->out_end;
uint32_t size = end - begin;
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
 
/*
* Write the character and increment the write pointer modulo the
* output buffer size. Note that if we are to rewrite a character
* which has not been read by the SGCN controller yet (i.e. the output
* buffer is full), we need to wait until the controller reads some more
* characters. We wait actively, which means that all threads waiting
* for the lock are blocked. However, this situation is
* 1) rare - the output buffer is big, so filling the whole
* output buffer is improbable
* 2) short-lasting - it will take the controller only a fraction
* of millisecond to pick the unread characters up
* 3) not serious - the blocked threads are those that print something
* to user console, which is not a time-critical operation
*/
uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
while (*out_rdptr_ptr == new_wrptr)
;
*buf_ptr = c;
*out_wrptr_ptr = new_wrptr;
}
 
/**
* SGCN output operation. Prints a single character to the SGCN. If the line
* feed character is written ('\n'), the carriage return character ('\r') is
* written straight away.
*/
static void sgcn_putchar(struct chardev * cd, const char c, bool silent)
{
if (!silent) {
spinlock_lock(&sgcn_output_lock);
sgcn_do_putchar(c);
if (c == '\n')
sgcn_do_putchar('\r');
spinlock_unlock(&sgcn_output_lock);
}
}
 
/**
* Called when actively reading the character. Not implemented yet.
*/
static char sgcn_key_read(chardev_t *d)
{
return (char) 0;
}
 
/**
* The driver works in polled mode, so no interrupt should be handled by it.
*/
static irq_ownership_t sgcn_claim(void)
{
return IRQ_DECLINE;
}
 
/**
* The driver works in polled mode, so no interrupt should be handled by it.
*/
static void sgcn_irq_handler(irq_t *irq, void *arg, ...)
{
panic("Not yet implemented, SGCN works in polled mode.");
}
 
/**
* Grabs the input for kernel.
*/
void sgcn_grab(void)
{
ipl_t ipl = interrupts_disable();
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
/* skip all the user typed before the grab and hasn't been processed */
spinlock_lock(&sgcn_input_lock);
*in_rdptr_ptr = *in_wrptr_ptr;
spinlock_unlock(&sgcn_input_lock);
 
spinlock_lock(&sgcn_irq.lock);
sgcn_irq.notif_cfg.notify = false;
spinlock_unlock(&sgcn_irq.lock);
interrupts_restore(ipl);
}
 
/**
* Releases the input so that userspace can use it.
*/
void sgcn_release(void)
{
ipl_t ipl = interrupts_disable();
spinlock_lock(&sgcn_irq.lock);
if (sgcn_irq.notif_cfg.answerbox)
sgcn_irq.notif_cfg.notify = true;
spinlock_unlock(&sgcn_irq.lock);
interrupts_restore(ipl);
}
 
/**
* Function regularly called by the keyboard polling thread. Finds out whether
* there are some unread characters in the input queue. If so, it picks them up
* and sends them to the upper layers of HelenOS.
*/
void sgcn_poll(void)
{
uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
uint32_t end = SGCN_BUFFER_HEADER->in_end;
uint32_t size = end - begin;
spinlock_lock(&sgcn_input_lock);
ipl_t ipl = interrupts_disable();
spinlock_lock(&sgcn_irq.lock);
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
if (*in_rdptr_ptr != *in_wrptr_ptr) {
if (sgcn_irq.notif_cfg.notify && sgcn_irq.notif_cfg.answerbox) {
ipc_irq_send_notif(&sgcn_irq);
spinlock_unlock(&sgcn_irq.lock);
interrupts_restore(ipl);
spinlock_unlock(&sgcn_input_lock);
return;
}
}
spinlock_unlock(&sgcn_irq.lock);
interrupts_restore(ipl);
 
while (*in_rdptr_ptr != *in_wrptr_ptr) {
buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
char c = *buf_ptr;
*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
if (c == '\r') {
c = '\n';
}
chardev_push_character(&sgcn_io, c);
}
spinlock_unlock(&sgcn_input_lock);
}
 
/**
* A public function which initializes I/O from/to Serengeti console
* and sets it as a default input/output.
*/
void sgcn_init(void)
{
sgcn_buffer_begin_init();
 
kbd_type = KBD_SGCN;
 
devno_t devno = device_assign_devno();
irq_initialize(&sgcn_irq);
sgcn_irq.devno = devno;
sgcn_irq.inr = FICTIONAL_INR;
sgcn_irq.claim = sgcn_claim;
sgcn_irq.handler = sgcn_irq_handler;
irq_register(&sgcn_irq);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.type", NULL, KBD_SGCN);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, FICTIONAL_INR);
sysinfo_set_item_val("fb.kind", NULL, 4);
chardev_initialize("sgcn_io", &sgcn_io, &sgcn_ops);
stdin = &sgcn_io;
stdout = &sgcn_io;
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/drivers/fhc.c
0,0 → 1,120
/*
* 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 sparc64
* @{
*/
/**
* @file
* @brief FireHose Controller (FHC) driver.
*
* Note that this driver is a result of reverse engineering
* rather than implementation of a specification. This
* is due to the fact that the FHC documentation is not
* publicly available.
*/
 
#include <arch/drivers/fhc.h>
#include <arch/trap/interrupt.h>
#include <mm/page.h>
#include <mm/slab.h>
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
 
fhc_t *central_fhc = NULL;
 
/**
* I suspect this must be hardcoded in the FHC.
* If it is not, than we can read all IMAP registers
* and get the complete mapping.
*/
#define FHC_UART_INR 0x39
 
#define FHC_UART_IMAP 0x0
#define FHC_UART_ICLR 0x4
 
#define UART_IMAP_REG 4
 
fhc_t *fhc_init(ofw_tree_node_t *node)
{
fhc_t *fhc;
ofw_tree_property_t *prop;
 
prop = ofw_tree_getprop(node, "reg");
if (!prop || !prop->value)
return NULL;
count_t regs = prop->size / sizeof(ofw_central_reg_t);
if (regs + 1 < UART_IMAP_REG)
return NULL;
 
ofw_central_reg_t *reg = &((ofw_central_reg_t *) prop->value)[UART_IMAP_REG];
 
uintptr_t paddr;
if (!ofw_central_apply_ranges(node->parent, reg, &paddr))
return NULL;
 
fhc = (fhc_t *) malloc(sizeof(fhc_t), FRAME_ATOMIC);
if (!fhc)
return NULL;
 
fhc->uart_imap = (uint32_t *) hw_map(paddr, reg->size);
return fhc;
}
 
void fhc_enable_interrupt(fhc_t *fhc, int inr)
{
switch (inr) {
case FHC_UART_INR:
fhc->uart_imap[FHC_UART_IMAP] |= IMAP_V_MASK;
break;
default:
panic("Unexpected INR (%d).", inr);
break;
}
}
 
void fhc_clear_interrupt(void *fhcp, int inr)
{
fhc_t *fhc = (fhc_t *)fhcp;
ASSERT(fhc->uart_imap);
 
switch (inr) {
case FHC_UART_INR:
fhc->uart_imap[FHC_UART_ICLR] = 0;
break;
default:
panic("Unexpected INR (%d).", inr);
break;
}
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/drivers/kbd.c
0,0 → 1,168
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch/drivers/kbd.h>
#include <genarch/ofw/ofw_tree.h>
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#endif
#include <ddi/device.h>
#include <ddi/irq.h>
#include <arch/mm/page.h>
#include <arch/types.h>
#include <align.h>
#include <func.h>
#include <print.h>
 
kbd_type_t kbd_type = KBD_UNKNOWN;
 
/** Initialize keyboard.
*
* Traverse OpenFirmware device tree in order to find necessary
* info about the keyboard device.
*
* @param node Keyboard device node.
*/
void kbd_init(ofw_tree_node_t *node)
{
size_t offset;
uintptr_t aligned_addr;
ofw_tree_property_t *prop;
const char *name;
cir_t cir;
void *cir_arg;
name = ofw_tree_node_name(node);
/*
* Determine keyboard serial controller type.
*/
if (strcmp(name, "zs") == 0)
kbd_type = KBD_Z8530;
else if (strcmp(name, "su") == 0)
kbd_type = KBD_NS16550;
if (kbd_type == KBD_UNKNOWN) {
printf("Unknown keyboard device.\n");
return;
}
/*
* Read 'interrupts' property.
*/
uint32_t interrupts;
prop = ofw_tree_getprop(node, "interrupts");
if ((!prop) || (!prop->value))
panic("Cannot find 'interrupt' property.");
interrupts = *((uint32_t *) prop->value);
/*
* Read 'reg' property.
*/
prop = ofw_tree_getprop(node, "reg");
if ((!prop) || (!prop->value))
panic("Cannot find 'reg' property.");
uintptr_t pa;
size_t size;
inr_t inr;
switch (kbd_type) {
case KBD_Z8530:
size = ((ofw_fhc_reg_t *) prop->value)->size;
if (!ofw_fhc_apply_ranges(node->parent,
((ofw_fhc_reg_t *) prop->value), &pa)) {
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_fhc_map_interrupt(node->parent,
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir,
&cir_arg)) {
printf("Failed to determine keyboard interrupt.\n");
return;
}
break;
case KBD_NS16550:
size = ((ofw_ebus_reg_t *) prop->value)->size;
if (!ofw_ebus_apply_ranges(node->parent,
((ofw_ebus_reg_t *) prop->value), &pa)) {
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_ebus_map_interrupt(node->parent,
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir,
&cir_arg)) {
printf("Failed to determine keyboard interrupt.\n");
return;
};
break;
default:
panic("Unexpected keyboard type.");
}
/*
* We need to pass aligned address to hw_map().
* However, the physical keyboard address can
* be pretty much unaligned, depending on the
* underlying controller.
*/
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
offset = pa - aligned_addr;
switch (kbd_type) {
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_init(device_assign_devno(),
hw_map(aligned_addr, offset + size) + offset, inr, cir, cir_arg);
break;
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_init(device_assign_devno(),
(ioport_t) (hw_map(aligned_addr, offset + size) + offset), inr, cir, cir_arg);
break;
#endif
default:
printf("Kernel is not compiled with the necessary keyboard "
"driver this machine requires.\n");
}
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/drivers/scr.c
0,0 → 1,246
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch/drivers/scr.h>
#include <genarch/ofw/ofw_tree.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <arch/types.h>
#include <func.h>
#include <align.h>
#include <print.h>
 
#define FFB_REG_24BPP 7
 
scr_type_t scr_type = SCR_UNKNOWN;
 
/** Initialize screen.
*
* Traverse OpenFirmware device tree in order to find necessary
* info about the screen device.
*
* @param node Screen device node.
*/
void scr_init(ofw_tree_node_t *node)
{
ofw_tree_property_t *prop;
ofw_pci_reg_t *pci_reg;
ofw_pci_reg_t pci_abs_reg;
ofw_upa_reg_t *upa_reg;
ofw_sbus_reg_t *sbus_reg;
const char *name;
name = ofw_tree_node_name(node);
if (strcmp(name, "SUNW,m64B") == 0)
scr_type = SCR_ATYFB;
else if (strcmp(name, "SUNW,XVR-100") == 0)
scr_type = SCR_XVR;
else if (strcmp(name, "SUNW,ffb") == 0)
scr_type = SCR_FFB;
else if (strcmp(name, "cgsix") == 0)
scr_type = SCR_CGSIX;
if (scr_type == SCR_UNKNOWN) {
printf("Unknown screen device.\n");
return;
}
uintptr_t fb_addr;
unsigned int fb_offset = 0;
uint32_t fb_width = 0;
uint32_t fb_height = 0;
uint32_t fb_depth = 0;
uint32_t fb_linebytes = 0;
uint32_t fb_scanline = 0;
unsigned int visual;
 
prop = ofw_tree_getprop(node, "width");
if (prop && prop->value)
fb_width = *((uint32_t *) prop->value);
 
prop = ofw_tree_getprop(node, "height");
if (prop && prop->value)
fb_height = *((uint32_t *) prop->value);
 
prop = ofw_tree_getprop(node, "depth");
if (prop && prop->value)
fb_depth = *((uint32_t *) prop->value);
 
prop = ofw_tree_getprop(node, "linebytes");
if (prop && prop->value)
fb_linebytes = *((uint32_t *) prop->value);
 
prop = ofw_tree_getprop(node, "reg");
if (!prop)
panic("Cannot find 'reg' property.");
 
switch (scr_type) {
case SCR_ATYFB:
if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
printf("Too few screen registers.\n");
return;
}
pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
printf("Failed to absolutize fb register.\n");
return;
}
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
&fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
switch (fb_depth) {
case 8:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_INDIRECT_8;
break;
case 16:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_5_6_5;
break;
case 24:
fb_scanline = fb_linebytes * 4;
visual = VISUAL_RGB_8_8_8_0;
break;
case 32:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_0_8_8_8;
break;
default:
printf("Unsupported bits per pixel.\n");
return;
}
break;
case SCR_XVR:
if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
printf("Too few screen registers.\n");
return;
}
pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
printf("Failed to absolutize fb register.\n");
return;
}
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
&fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
 
fb_offset = 4 * 0x2000;
 
switch (fb_depth) {
case 8:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_INDIRECT_8;
break;
case 16:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_5_6_5;
break;
case 24:
fb_scanline = fb_linebytes * 4;
visual = VISUAL_RGB_8_8_8_0;
break;
case 32:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_0_8_8_8;
break;
default:
printf("Unsupported bits per pixel.\n");
return;
}
break;
case SCR_FFB:
fb_scanline = 8192;
visual = VISUAL_BGR_0_8_8_8;
 
upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
 
break;
case SCR_CGSIX:
switch (fb_depth) {
case 8:
fb_scanline = fb_linebytes;
visual = VISUAL_INDIRECT_8;
break;
default:
printf("Not implemented.\n");
return;
}
sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0];
if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
break;
default:
panic("Unexpected type.");
}
 
fb_properties_t props = {
.addr = fb_addr,
.offset = fb_offset,
.x = fb_width,
.y = fb_height,
.scan = fb_scanline,
.visual = visual,
};
fb_init(&props);
}
 
void scr_redraw(void)
{
fb_redraw();
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/drivers/tick.c
0,0 → 1,125
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch/drivers/tick.h>
#include <arch/interrupt.h>
#include <arch/sparc64.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <arch/cpu.h>
#include <arch/boot/boot.h>
#include <time/clock.h>
#include <arch.h>
#include <debug.h>
 
#define TICK_RESTART_TIME 50 /* Worst case estimate. */
 
/** Initialize tick and stick interrupt. */
void tick_init(void)
{
/* initialize TICK interrupt */
tick_compare_reg_t compare;
 
interrupt_register(14, "tick_int", tick_interrupt);
compare.int_dis = false;
compare.tick_cmpr = CPU->arch.clock_frequency / HZ;
CPU->arch.next_tick_cmpr = compare.tick_cmpr;
tick_compare_write(compare.value);
tick_write(0);
 
#if defined (US3)
/* disable STICK interrupts and clear any pending ones */
tick_compare_reg_t stick_compare;
softint_reg_t clear;
 
stick_compare.value = stick_compare_read();
stick_compare.int_dis = true;
stick_compare.tick_cmpr = 0;
stick_compare_write(stick_compare.value);
 
clear.value = 0;
clear.stick_int = 1;
clear_softint_write(clear.value);
#endif
}
 
/** Process tick interrupt.
*
* @param n Interrupt Level, 14, (can be ignored)
* @param istate Interrupted state.
*/
void tick_interrupt(int n, istate_t *istate)
{
softint_reg_t softint, clear;
uint64_t drift;
 
softint.value = softint_read();
/*
* Make sure we are servicing interrupt_level_14
*/
ASSERT(n == 14);
/*
* Make sure we are servicing TICK_INT.
*/
ASSERT(softint.tick_int);
 
/*
* Clear tick interrupt.
*/
clear.value = 0;
clear.tick_int = 1;
clear_softint_write(clear.value);
/*
* Reprogram the compare register.
* For now, we can ignore the potential of the registers to overflow.
* On a 360MHz Ultra 60, the 63-bit compare counter will overflow in
* about 812 years. If there was a 2GHz UltraSPARC computer, it would
* overflow only in 146 years.
*/
drift = tick_read() - CPU->arch.next_tick_cmpr;
while (drift > CPU->arch.clock_frequency / HZ) {
drift -= CPU->arch.clock_frequency / HZ;
CPU->missed_clock_ticks++;
}
CPU->arch.next_tick_cmpr = tick_read() +
(CPU->arch.clock_frequency / HZ) - drift;
tick_compare_write(CPU->arch.next_tick_cmpr);
clock();
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/drivers/pci.c
0,0 → 1,220
/*
* 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 sparc64
* @{
*/
/**
* @file
* @brief PCI driver.
*/
 
#include <arch/drivers/pci.h>
#include <genarch/ofw/ofw_tree.h>
#include <arch/trap/interrupt.h>
#include <mm/page.h>
#include <mm/slab.h>
#include <arch/types.h>
#include <debug.h>
#include <print.h>
#include <func.h>
#include <arch/asm.h>
 
#define SABRE_INTERNAL_REG 0
#define PSYCHO_INTERNAL_REG 2
 
#define OBIO_IMR_BASE 0x200
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK))
 
#define OBIO_CIR_BASE 0x300
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK))
 
static void obio_enable_interrupt(pci_t *, int);
static void obio_clear_interrupt(pci_t *, int);
 
static pci_t *pci_sabre_init(ofw_tree_node_t *);
static pci_t *pci_psycho_init(ofw_tree_node_t *);
 
/** PCI operations for Sabre model. */
static pci_operations_t pci_sabre_ops = {
.enable_interrupt = obio_enable_interrupt,
.clear_interrupt = obio_clear_interrupt
};
/** PCI operations for Psycho model. */
static pci_operations_t pci_psycho_ops = {
.enable_interrupt = obio_enable_interrupt,
.clear_interrupt = obio_clear_interrupt
};
 
/** Initialize PCI controller (model Sabre).
*
* @param node OpenFirmware device tree node of the Sabre.
*
* @return Address of the initialized PCI structure.
*/
pci_t *pci_sabre_init(ofw_tree_node_t *node)
{
pci_t *pci;
ofw_tree_property_t *prop;
 
/*
* Get registers.
*/
prop = ofw_tree_getprop(node, "reg");
if (!prop || !prop->value)
return NULL;
 
ofw_upa_reg_t *reg = prop->value;
count_t regs = prop->size / sizeof(ofw_upa_reg_t);
 
if (regs < SABRE_INTERNAL_REG + 1)
return NULL;
 
uintptr_t paddr;
if (!ofw_upa_apply_ranges(node->parent, &reg[SABRE_INTERNAL_REG],
&paddr))
return NULL;
 
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC);
if (!pci)
return NULL;
 
pci->model = PCI_SABRE;
pci->op = &pci_sabre_ops;
pci->reg = (uint64_t *) hw_map(paddr, reg[SABRE_INTERNAL_REG].size);
 
return pci;
}
 
 
/** Initialize the Psycho PCI controller.
*
* @param node OpenFirmware device tree node of the Psycho.
*
* @return Address of the initialized PCI structure.
*/
pci_t *pci_psycho_init(ofw_tree_node_t *node)
{
pci_t *pci;
ofw_tree_property_t *prop;
 
/*
* Get registers.
*/
prop = ofw_tree_getprop(node, "reg");
if (!prop || !prop->value)
return NULL;
 
ofw_upa_reg_t *reg = prop->value;
count_t regs = prop->size / sizeof(ofw_upa_reg_t);
 
if (regs < PSYCHO_INTERNAL_REG + 1)
return NULL;
 
uintptr_t paddr;
if (!ofw_upa_apply_ranges(node->parent, &reg[PSYCHO_INTERNAL_REG],
&paddr))
return NULL;
 
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC);
if (!pci)
return NULL;
 
pci->model = PCI_PSYCHO;
pci->op = &pci_psycho_ops;
pci->reg = (uint64_t *) hw_map(paddr, reg[PSYCHO_INTERNAL_REG].size);
 
return pci;
}
 
void obio_enable_interrupt(pci_t *pci, int inr)
{
pci->reg[OBIO_IMR(inr & INO_MASK)] |= IMAP_V_MASK;
}
 
void obio_clear_interrupt(pci_t *pci, int inr)
{
pci->reg[OBIO_CIR(inr & INO_MASK)] = 0; /* set IDLE */
}
 
/** Initialize PCI controller. */
pci_t *pci_init(ofw_tree_node_t *node)
{
ofw_tree_property_t *prop;
 
/*
* First, verify this is a PCI node.
*/
ASSERT(strcmp(ofw_tree_node_name(node), "pci") == 0);
 
/*
* Determine PCI controller model.
*/
prop = ofw_tree_getprop(node, "model");
if (!prop || !prop->value)
return NULL;
if (strcmp(prop->value, "SUNW,sabre") == 0) {
/*
* PCI controller Sabre.
* This model is found on UltraSPARC IIi based machines.
*/
return pci_sabre_init(node);
} else if (strcmp(prop->value, "SUNW,psycho") == 0) {
/*
* PCI controller Psycho.
* Used on UltraSPARC II based processors, for instance,
* on Ultra 60.
*/
return pci_psycho_init(node);
} else {
/*
* Unsupported model.
*/
printf("Unsupported PCI controller model (%s).\n", prop->value);
}
 
return NULL;
}
 
void pci_enable_interrupt(pci_t *pci, int inr)
{
ASSERT(pci->op && pci->op->enable_interrupt);
pci->op->enable_interrupt(pci, inr);
}
 
void pci_clear_interrupt(void *pcip, int inr)
{
pci_t *pci = (pci_t *)pcip;
 
ASSERT(pci->op && pci->op->clear_interrupt);
pci->op->clear_interrupt(pci, inr);
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/smp/ipi.c
0,0 → 1,174
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#include <smp/ipi.h>
#include <cpu.h>
#include <arch.h>
#include <arch/cpu.h>
#include <arch/asm.h>
#include <config.h>
#include <mm/tlb.h>
#include <arch/interrupt.h>
#include <arch/trap/interrupt.h>
#include <arch/barrier.h>
#include <preemption.h>
#include <time/delay.h>
#include <panic.h>
 
/** Set the contents of the outgoing interrupt vector data.
*
* The first data item (data 0) will be set to the value of func, the
* rest of the vector will contain zeros.
*
* This is a helper function used from within the cross_call function.
*
* @param func value the first data item of the vector will be set to
*/
static inline void set_intr_w_data(void (* func)(void))
{
#if defined (US)
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t) func);
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
#elif defined (US3)
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_0, (uintptr_t) func);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_1, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_2, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_3, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_4, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_5, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_6, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_7, 0);
#endif
}
 
/** Invoke function on another processor.
*
* Currently, only functions without arguments are supported.
* Supporting more arguments in the future should be no big deal.
*
* Interrupts must be disabled prior to this call.
*
* @param mid MID of the target processor.
* @param func Function to be invoked.
*/
static void cross_call(int mid, void (* func)(void))
{
uint64_t status;
bool done;
 
/*
* This function might enable interrupts for a while.
* In order to prevent migration to another processor,
* we explicitly disable preemption.
*/
preemption_disable();
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
if (status & INTR_DISPATCH_STATUS_BUSY)
panic("Interrupt Dispatch Status busy bit set.");
ASSERT(!(pstate_read() & PSTATE_IE_BIT));
do {
set_intr_w_data(func);
asi_u64_write(ASI_INTR_W,
(mid << INTR_VEC_DISPATCH_MID_SHIFT) |
VA_INTR_W_DISPATCH, 0);
membar();
do {
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
} while (status & INTR_DISPATCH_STATUS_BUSY);
done = !(status & INTR_DISPATCH_STATUS_NACK);
if (!done) {
/*
* Prevent deadlock.
*/
(void) interrupts_enable();
delay(20 + (tick_read() & 0xff));
(void) interrupts_disable();
}
} while (done);
preemption_enable();
}
 
/*
* Deliver IPI to all processors except the current one.
*
* The sparc64 architecture does not support any group addressing
* which is found, for instance, on ia32 and amd64. Therefore we
* need to simulate the broadcast by sending the message to
* all target processors step by step.
*
* We assume that interrupts are disabled.
*
* @param ipi IPI number.
*/
void ipi_broadcast_arch(int ipi)
{
unsigned int i;
void (* func)(void);
switch (ipi) {
case IPI_TLB_SHOOTDOWN:
func = tlb_shootdown_ipi_recv;
break;
default:
panic("Unknown IPI (%d).", ipi);
break;
}
/*
* As long as we don't support hot-plugging
* or hot-unplugging of CPUs, we can walk
* the cpus array and read processor's MID
* without locking.
*/
for (i = 0; i < config.cpu_active; i++) {
if (&cpus[i] == CPU)
continue; /* skip the current CPU */
 
cross_call(cpus[i].arch.mid, func);
}
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/smp/smp.c
0,0 → 1,137
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#include <smp/smp.h>
#include <genarch/ofw/ofw_tree.h>
#include <cpu.h>
#include <arch/cpu_family.h>
#include <arch/cpu.h>
#include <arch.h>
#include <config.h>
#include <macros.h>
#include <arch/types.h>
#include <synch/synch.h>
#include <synch/waitq.h>
#include <print.h>
#include <arch/cpu_node.h>
 
/**
* This global variable is used to pick-up application processors
* from their active loop in start.S. When a processor looping in
* start.S sees that this variable contains its MID, it can
* proceed with its initialization.
*
* This variable is modified only by the bootstrap processor.
* Other processors access it read-only.
*/
volatile uint64_t waking_up_mid = (uint64_t) -1;
 
/** Determine number of processors. */
void smp_init(void)
{
ofw_tree_node_t *node;
count_t cnt = 0;
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
while (node) {
cnt++;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
}
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
cnt += 2;
node = ofw_tree_find_peer_by_name(node, "cmp");
}
}
config.cpu_count = max(1, cnt);
}
 
/**
* Wakes up the CPU which is represented by the "node" OFW tree node.
* If "node" represents the current CPU, calling the function has
* no effect.
*/
static void wakeup_cpu(ofw_tree_node_t *node)
{
uint32_t mid;
ofw_tree_property_t *prop;
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
prop = ofw_tree_getprop(node, "upa-portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "cpuid");
if (!prop || prop->value == NULL)
return;
mid = *((uint32_t *) prop->value);
if (CPU->arch.mid == mid)
return;
 
waking_up_mid = mid;
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) ==
ESYNCH_TIMEOUT)
printf("%s: waiting for processor (mid = %" PRIu32
") timed out\n", __func__, mid);
}
 
/** Wake application processors up. */
void kmp(void *arg)
{
ofw_tree_node_t *node;
int i;
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
for (i = 0; node;
node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++)
wakeup_cpu(node);
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
wakeup_cpu(ofw_tree_find_child(node, "cpu@0"));
wakeup_cpu(ofw_tree_find_child(node, "cpu@1"));
node = ofw_tree_find_peer_by_name(node, "cmp");
}
}
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/sparc64.c
0,0 → 1,165
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <debug.h>
#include <config.h>
#include <arch/trap/trap.h>
#include <arch/console.h>
#include <proc/thread.h>
#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 <genarch/ofw/ofw_tree.h>
#include <userspace.h>
#include <ddi/irq.h>
 
bootinfo_t bootinfo;
 
/** Perform sparc64 specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Copy init task info. */
init.cnt = bootinfo.taskmap.count;
uint32_t i;
 
for (i = 0; i < bootinfo.taskmap.count; i++) {
init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr;
init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
}
/* Copy boot allocations info. */
ballocs.base = bootinfo.ballocs.base;
ballocs.size = bootinfo.ballocs.size;
ofw_tree_init(bootinfo.ofw_root);
}
 
/** Perform sparc64 specific initialization before mm is initialized. */
void arch_pre_mm_init(void)
{
if (config.cpu_active == 1)
trap_init();
}
 
/** Perform sparc64 specific initialization afterr mm is initialized. */
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
/*
* We have 2^11 different interrupt vectors.
* But we only create 128 buckets.
*/
irq_init(1 << 11, 128);
 
standalone_sparc64_console_init();
}
}
 
void arch_post_cpu_init(void)
{
}
 
void arch_pre_smp_init(void)
{
}
 
void arch_post_smp_init(void)
{
static thread_t *t = NULL;
 
 
if (!t) {
/*
* Create thread that polls keyboard.
*/
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("Cannot create kkbdpoll.");
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)
{
switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE
- (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
(uintptr_t) kernel_uarg->uspace_uarg);
 
for (;;)
;
/* not reached */
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/trap/exception.c
0,0 → 1,220
/*
* Copyright (c) 2005 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 sparc64interrupt
* @{
*/
/** @file
*
*/
 
#include <arch/trap/exception.h>
#include <arch/mm/tlb.h>
#include <arch/interrupt.h>
#include <interrupt.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <debug.h>
#include <symtab.h>
#include <print.h>
 
void dump_istate(istate_t *istate)
{
printf("TSTATE=%#" PRIx64 "\n", istate->tstate);
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, get_symtab_entry(istate->tpc));
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, get_symtab_entry(istate->tnpc));
}
 
/** Handle instruction_access_exception. (0x8) */
void instruction_access_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle instruction_access_error. (0xa) */
void instruction_access_error(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle illegal_instruction. (0x10) */
void illegal_instruction(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle privileged_opcode. (0x11) */
void privileged_opcode(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle unimplemented_LDD. (0x12) */
void unimplemented_LDD(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle unimplemented_STD. (0x13) */
void unimplemented_STD(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle fp_disabled. (0x20) */
void fp_disabled(int n, istate_t *istate)
{
fprs_reg_t fprs;
fprs.value = fprs_read();
if (!fprs.fef) {
fprs.fef = true;
fprs_write(fprs.value);
return;
}
 
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
#endif
}
 
/** Handle fp_exception_ieee_754. (0x21) */
void fp_exception_ieee_754(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle fp_exception_other. (0x22) */
void fp_exception_other(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle tag_overflow. (0x23) */
void tag_overflow(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle division_by_zero. (0x28) */
void division_by_zero(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle data_access_exception. (0x30) */
void data_access_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
dump_sfsr_and_sfar();
panic("%s.", __func__);
}
 
/** Handle data_access_error. (0x32) */
void data_access_error(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle mem_address_not_aligned. (0x34) */
void mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle LDDF_mem_address_not_aligned. (0x35) */
void LDDF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle STDF_mem_address_not_aligned. (0x36) */
void STDF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle privileged_action. (0x37) */
void privileged_action(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle LDQF_mem_address_not_aligned. (0x38) */
void LDQF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** Handle STQF_mem_address_not_aligned. (0x39) */
void STQF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s.", __func__);
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/trap/interrupt.c
0,0 → 1,124
/*
* Copyright (c) 2005 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 sparc64interrupt
* @{
*/
/** @file
*/
 
#include <arch/interrupt.h>
#include <arch/sparc64.h>
#include <arch/trap/interrupt.h>
#include <interrupt.h>
#include <ddi/irq.h>
#include <arch/types.h>
#include <debug.h>
#include <arch/asm.h>
#include <arch/barrier.h>
#include <print.h>
#include <arch.h>
#include <mm/tlb.h>
#include <config.h>
#include <synch/spinlock.h>
 
/** Register Interrupt Level Handler.
*
* @param n Interrupt Level (1 - 15).
* @param name Short descriptive string.
* @param f Handler.
*/
void interrupt_register(int n, const char *name, iroutine f)
{
ASSERT(n >= IVT_FIRST && n <= IVT_ITEMS);
exc_register(n - 1, name, f);
}
 
/** Process hardware interrupt.
*
* @param n Ignored.
* @param istate Ignored.
*/
void interrupt(int n, istate_t *istate)
{
uint64_t status;
uint64_t intrcv;
uint64_t data0;
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
if (status & (!INTR_DISPATCH_STATUS_BUSY))
panic("Interrupt Dispatch Status busy bit not set.");
 
intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
#if defined (US)
data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);
#elif defined (US3)
data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);
#endif
 
irq_t *irq = irq_dispatch_and_lock(data0);
if (irq) {
/*
* The IRQ handler was found.
*/
irq->handler(irq, irq->arg);
/*
* See if there is a clear-interrupt-routine and call it.
*/
if (irq->cir) {
irq->cir(irq->cir_arg, irq->inr);
}
spinlock_unlock(&irq->lock);
} else if (data0 > config.base) {
/*
* This is a cross-call.
* data0 contains address of the kernel function.
* We call the function only after we verify
* it is one of the supported ones.
*/
#ifdef CONFIG_SMP
if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
tlb_shootdown_ipi_recv();
}
#endif
} else {
/*
* Spurious interrupt.
*/
#ifdef CONFIG_DEBUG
printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64
", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
#endif
}
 
membar();
asi_u64_write(ASI_INTR_RECEIVE, 0, 0);
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/trap/trap_table.S
0,0 → 1,851
#
# Copyright (c) 2005 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.
#
 
/**
* @file
* @brief This file contains kernel trap table.
*/
 
.register %g2, #scratch
.register %g3, #scratch
 
.text
 
#include <arch/trap/trap_table.h>
#include <arch/trap/regwin.h>
#include <arch/trap/interrupt.h>
#include <arch/trap/exception.h>
#include <arch/trap/syscall.h>
#include <arch/trap/mmu.h>
#include <arch/mm/mmu.h>
#include <arch/mm/page.h>
#include <arch/stack.h>
#include <arch/regdef.h>
 
#define TABLE_SIZE TRAP_TABLE_SIZE
#define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE
 
/*
* Kernel trap table.
*/
.align TABLE_SIZE
.global trap_table
trap_table:
 
/* TT = 0x08, TL = 0, instruction_access_exception */
.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
.global instruction_access_exception_tl0
instruction_access_exception_tl0:
wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
PREEMPTIBLE_HANDLER instruction_access_exception
 
/* TT = 0x0a, TL = 0, instruction_access_error */
.org trap_table + TT_INSTRUCTION_ACCESS_ERROR*ENTRY_SIZE
.global instruction_access_error_tl0
instruction_access_error_tl0:
PREEMPTIBLE_HANDLER instruction_access_error
 
/* TT = 0x10, TL = 0, illegal_instruction */
.org trap_table + TT_ILLEGAL_INSTRUCTION*ENTRY_SIZE
.global illegal_instruction_tl0
illegal_instruction_tl0:
PREEMPTIBLE_HANDLER illegal_instruction
 
/* TT = 0x11, TL = 0, privileged_opcode */
.org trap_table + TT_PRIVILEGED_OPCODE*ENTRY_SIZE
.global privileged_opcode_tl0
privileged_opcode_tl0:
PREEMPTIBLE_HANDLER privileged_opcode
 
/* TT = 0x12, TL = 0, unimplemented_LDD */
.org trap_table + TT_UNIMPLEMENTED_LDD*ENTRY_SIZE
.global unimplemented_LDD_tl0
unimplemented_LDD_tl0:
PREEMPTIBLE_HANDLER unimplemented_LDD
 
/* TT = 0x13, TL = 0, unimplemented_STD */
.org trap_table + TT_UNIMPLEMENTED_STD*ENTRY_SIZE
.global unimplemented_STD_tl0
unimplemented_STD_tl0:
PREEMPTIBLE_HANDLER unimplemented_STD
 
/* TT = 0x20, TL = 0, fb_disabled handler */
.org trap_table + TT_FP_DISABLED*ENTRY_SIZE
.global fb_disabled_tl0
fp_disabled_tl0:
PREEMPTIBLE_HANDLER fp_disabled
 
/* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
.org trap_table + TT_FP_EXCEPTION_IEEE_754*ENTRY_SIZE
.global fb_exception_ieee_754_tl0
fp_exception_ieee_754_tl0:
PREEMPTIBLE_HANDLER fp_exception_ieee_754
 
/* TT = 0x22, TL = 0, fb_exception_other handler */
.org trap_table + TT_FP_EXCEPTION_OTHER*ENTRY_SIZE
.global fb_exception_other_tl0
fp_exception_other_tl0:
PREEMPTIBLE_HANDLER fp_exception_other
 
/* TT = 0x23, TL = 0, tag_overflow */
.org trap_table + TT_TAG_OVERFLOW*ENTRY_SIZE
.global tag_overflow_tl0
tag_overflow_tl0:
PREEMPTIBLE_HANDLER tag_overflow
 
/* TT = 0x24, TL = 0, clean_window handler */
.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
.global clean_window_tl0
clean_window_tl0:
CLEAN_WINDOW_HANDLER
 
/* TT = 0x28, TL = 0, division_by_zero */
.org trap_table + TT_DIVISION_BY_ZERO*ENTRY_SIZE
.global division_by_zero_tl0
division_by_zero_tl0:
PREEMPTIBLE_HANDLER division_by_zero
 
/* TT = 0x30, TL = 0, data_access_exception */
.org trap_table + TT_DATA_ACCESS_EXCEPTION*ENTRY_SIZE
.global data_access_exception_tl0
data_access_exception_tl0:
wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
PREEMPTIBLE_HANDLER data_access_exception
 
/* TT = 0x32, TL = 0, data_access_error */
.org trap_table + TT_DATA_ACCESS_ERROR*ENTRY_SIZE
.global data_access_error_tl0
data_access_error_tl0:
PREEMPTIBLE_HANDLER data_access_error
 
/* TT = 0x34, TL = 0, mem_address_not_aligned */
.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
.global mem_address_not_aligned_tl0
mem_address_not_aligned_tl0:
PREEMPTIBLE_HANDLER mem_address_not_aligned
 
/* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
.org trap_table + TT_LDDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
.global LDDF_mem_address_not_aligned_tl0
LDDF_mem_address_not_aligned_tl0:
PREEMPTIBLE_HANDLER LDDF_mem_address_not_aligned
 
/* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
.org trap_table + TT_STDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
.global STDF_mem_address_not_aligned_tl0
STDF_mem_address_not_aligned_tl0:
PREEMPTIBLE_HANDLER STDF_mem_address_not_aligned
 
/* TT = 0x37, TL = 0, privileged_action */
.org trap_table + TT_PRIVILEGED_ACTION*ENTRY_SIZE
.global privileged_action_tl0
privileged_action_tl0:
PREEMPTIBLE_HANDLER privileged_action
 
/* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
.org trap_table + TT_LDQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
.global LDQF_mem_address_not_aligned_tl0
LDQF_mem_address_not_aligned_tl0:
PREEMPTIBLE_HANDLER LDQF_mem_address_not_aligned
 
/* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
.org trap_table + TT_STQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
.global STQF_mem_address_not_aligned_tl0
STQF_mem_address_not_aligned_tl0:
PREEMPTIBLE_HANDLER STQF_mem_address_not_aligned
 
/* TT = 0x41, TL = 0, interrupt_level_1 handler */
.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
.global interrupt_level_1_handler_tl0
interrupt_level_1_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 1
 
/* TT = 0x42, TL = 0, interrupt_level_2 handler */
.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
.global interrupt_level_2_handler_tl0
interrupt_level_2_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 2
 
/* TT = 0x43, TL = 0, interrupt_level_3 handler */
.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
.global interrupt_level_3_handler_tl0
interrupt_level_3_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 3
 
/* TT = 0x44, TL = 0, interrupt_level_4 handler */
.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
.global interrupt_level_4_handler_tl0
interrupt_level_4_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 4
 
/* TT = 0x45, TL = 0, interrupt_level_5 handler */
.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
.global interrupt_level_5_handler_tl0
interrupt_level_5_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 5
 
/* TT = 0x46, TL = 0, interrupt_level_6 handler */
.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
.global interrupt_level_6_handler_tl0
interrupt_level_6_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 6
 
/* TT = 0x47, TL = 0, interrupt_level_7 handler */
.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
.global interrupt_level_7_handler_tl0
interrupt_level_7_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 7
 
/* TT = 0x48, TL = 0, interrupt_level_8 handler */
.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
.global interrupt_level_8_handler_tl0
interrupt_level_8_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 8
 
/* TT = 0x49, TL = 0, interrupt_level_9 handler */
.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
.global interrupt_level_9_handler_tl0
interrupt_level_9_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 9
 
/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
.global interrupt_level_10_handler_tl0
interrupt_level_10_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 10
 
/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
.global interrupt_level_11_handler_tl0
interrupt_level_11_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 11
 
/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
.global interrupt_level_12_handler_tl0
interrupt_level_12_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 12
 
/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
.global interrupt_level_13_handler_tl0
interrupt_level_13_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 13
 
/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
.global interrupt_level_14_handler_tl0
interrupt_level_14_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 14
 
/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
.global interrupt_level_15_handler_tl0
interrupt_level_15_handler_tl0:
INTERRUPT_LEVEL_N_HANDLER 15
 
/* TT = 0x60, TL = 0, interrupt_vector_trap handler */
.org trap_table + TT_INTERRUPT_VECTOR_TRAP*ENTRY_SIZE
.global interrupt_vector_trap_handler_tl0
interrupt_vector_trap_handler_tl0:
INTERRUPT_VECTOR_TRAP_HANDLER
 
/* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
.org trap_table + TT_FAST_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
.global fast_instruction_access_mmu_miss_handler_tl0
fast_instruction_access_mmu_miss_handler_tl0:
FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
 
/* TT = 0x68, TL = 0, fast_data_access_MMU_miss */
.org trap_table + TT_FAST_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
.global fast_data_access_mmu_miss_handler_tl0
fast_data_access_mmu_miss_handler_tl0:
FAST_DATA_ACCESS_MMU_MISS_HANDLER 0
 
/* TT = 0x6c, TL = 0, fast_data_access_protection */
.org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE
.global fast_data_access_protection_handler_tl0
fast_data_access_protection_handler_tl0:
FAST_DATA_ACCESS_PROTECTION_HANDLER 0
 
/* TT = 0x80, TL = 0, spill_0_normal handler */
.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
.global spill_0_normal_tl0
spill_0_normal_tl0:
SPILL_NORMAL_HANDLER_KERNEL
 
/* TT = 0x84, TL = 0, spill_1_normal handler */
.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE
.global spill_1_normal_tl0
spill_1_normal_tl0:
SPILL_NORMAL_HANDLER_USERSPACE
 
/* TT = 0x88, TL = 0, spill_2_normal handler */
.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE
.global spill_2_normal_tl0
spill_2_normal_tl0:
SPILL_TO_USPACE_WINDOW_BUFFER
 
/* TT = 0xa0, TL = 0, spill_0_other handler */
.org trap_table + TT_SPILL_0_OTHER*ENTRY_SIZE
.global spill_0_other_tl0
spill_0_other_tl0:
SPILL_TO_USPACE_WINDOW_BUFFER
 
/* TT = 0xc0, TL = 0, fill_0_normal handler */
.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
.global fill_0_normal_tl0
fill_0_normal_tl0:
FILL_NORMAL_HANDLER_KERNEL
 
/* TT = 0xc4, TL = 0, fill_1_normal handler */
.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE
.global fill_1_normal_tl0
fill_1_normal_tl0:
FILL_NORMAL_HANDLER_USERSPACE
 
/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */
.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\
58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\
77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\
127
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
.global trap_instruction_\cur\()_tl0
trap_instruction_\cur\()_tl0:
ba trap_instruction_handler
mov \cur, %g2
.endr
 
/*
* Handlers for TL>0.
*/
 
/* TT = 0x08, TL > 0, instruction_access_exception */
.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
.global instruction_access_exception_tl1
instruction_access_exception_tl1:
wrpr %g0, 1, %tl
wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
PREEMPTIBLE_HANDLER instruction_access_exception
 
/* TT = 0x0a, TL > 0, instruction_access_error */
.org trap_table + (TT_INSTRUCTION_ACCESS_ERROR+512)*ENTRY_SIZE
.global instruction_access_error_tl1
instruction_access_error_tl1:
wrpr %g0, 1, %tl
PREEMPTIBLE_HANDLER instruction_access_error
 
/* TT = 0x10, TL > 0, illegal_instruction */
.org trap_table + (TT_ILLEGAL_INSTRUCTION+512)*ENTRY_SIZE
.global illegal_instruction_tl1
illegal_instruction_tl1:
wrpr %g0, 1, %tl
PREEMPTIBLE_HANDLER illegal_instruction
 
/* TT = 0x24, TL > 0, clean_window handler */
.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
.global clean_window_tl1
clean_window_tl1:
CLEAN_WINDOW_HANDLER
 
/* TT = 0x28, TL > 0, division_by_zero */
.org trap_table + (TT_DIVISION_BY_ZERO+512)*ENTRY_SIZE
.global division_by_zero_tl1
division_by_zero_tl1:
wrpr %g0, 1, %tl
PREEMPTIBLE_HANDLER division_by_zero
 
/* TT = 0x30, TL > 0, data_access_exception */
.org trap_table + (TT_DATA_ACCESS_EXCEPTION+512)*ENTRY_SIZE
.global data_access_exception_tl1
data_access_exception_tl1:
wrpr %g0, 1, %tl
wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
PREEMPTIBLE_HANDLER data_access_exception
 
/* TT = 0x32, TL > 0, data_access_error */
.org trap_table + (TT_DATA_ACCESS_ERROR+512)*ENTRY_SIZE
.global data_access_error_tl1
data_access_error_tl1:
wrpr %g0, 1, %tl
PREEMPTIBLE_HANDLER data_access_error
 
/* TT = 0x34, TL > 0, mem_address_not_aligned */
.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
.global mem_address_not_aligned_tl1
mem_address_not_aligned_tl1:
wrpr %g0, 1, %tl
PREEMPTIBLE_HANDLER mem_address_not_aligned
 
/* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
.org trap_table + (TT_FAST_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
.global fast_data_access_mmu_miss_handler_tl1
fast_data_access_mmu_miss_handler_tl1:
FAST_DATA_ACCESS_MMU_MISS_HANDLER 1
 
/* TT = 0x6c, TL > 0, fast_data_access_protection */
.org trap_table + (TT_FAST_DATA_ACCESS_PROTECTION+512)*ENTRY_SIZE
.global fast_data_access_protection_handler_tl1
fast_data_access_protection_handler_tl1:
FAST_DATA_ACCESS_PROTECTION_HANDLER 1
 
/* TT = 0x80, TL > 0, spill_0_normal handler */
.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
.global spill_0_normal_tl1
spill_0_normal_tl1:
SPILL_NORMAL_HANDLER_KERNEL
 
/* TT = 0x88, TL > 0, spill_2_normal handler */
.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE
.global spill_2_normal_tl1
spill_2_normal_tl1:
SPILL_TO_USPACE_WINDOW_BUFFER
 
/* TT = 0xa0, TL > 0, spill_0_other handler */
.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE
.global spill_0_other_tl1
spill_0_other_tl1:
SPILL_TO_USPACE_WINDOW_BUFFER
 
/* TT = 0xc0, TL > 0, fill_0_normal handler */
.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
.global fill_0_normal_tl1
fill_0_normal_tl1:
FILL_NORMAL_HANDLER_KERNEL
 
.align TABLE_SIZE
 
 
#define NOT(x) ((x) == 0)
 
/* Preemptible trap handler for TL=1.
*
* This trap handler makes arrangements to make calling of scheduler() from
* within a trap context possible. It is called from several other trap
* handlers.
*
* This function can be entered either with interrupt globals or alternate
* globals. Memory management trap handlers are obliged to switch to one of
* those global sets prior to calling this function. Register window management
* functions are not allowed to modify the alternate global registers.
*
* The kernel is designed to work on trap levels 0 - 4. For instance, the
* following can happen:
* TL0: kernel thread runs (CANSAVE=0, kernel stack not in DTLB)
* TL1: preemptible trap handler started after a tick interrupt
* TL2: preemptible trap handler did SAVE
* TL3: spill handler touched the kernel stack
* TL4: hardware or software failure
*
* Input registers:
* %g1 Address of function to call if this is not a syscall.
* %g2 First argument for the function.
* %g6 Pre-set as kernel stack base if trap from userspace.
* %g7 Pre-set as address of the userspace window buffer.
*/
.macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
/*
* ASSERT(%tl == 1)
*/
rdpr %tl, %g3
cmp %g3, 1
be 1f
nop
0: ba 0b ! this is for debugging, if we ever get here
nop ! it will be easy to find
 
1:
.if NOT(\is_syscall)
rdpr %tstate, %g3
/*
* One of the ways this handler can be invoked is after a nested MMU trap from
* either spill_1_normal or fill_1_normal traps. Both of these traps manipulate
* the CWP register. We deal with the situation by simulating the MMU trap
* on TL=1 and restart the respective SAVE or RESTORE instruction once the MMU
* trap is resolved. However, because we are in the wrong window from the
* perspective of the MMU trap, we need to synchronize CWP with CWP from TL=0.
*/
and %g3, TSTATE_CWP_MASK, %g4
wrpr %g4, 0, %cwp ! resynchronize CWP
 
andcc %g3, TSTATE_PRIV_BIT, %g0 ! if this trap came from the privileged mode...
bnz 0f ! ...skip setting of kernel stack and primary context
nop
.endif
/*
* Normal window spills will go to the userspace window buffer.
*/
wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(2), %wstate
 
wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent unnecessary clean_window exceptions
 
/*
* Switch to kernel stack. The old stack is
* automatically saved in the old window's %sp
* and the new window's %fp.
*/
save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
 
.if \is_syscall
/*
* Copy arguments for the syscall to the new window.
*/
mov %i0, %o0
mov %i1, %o1
mov %i2, %o2
mov %i3, %o3
mov %i4, %o4
mov %i5, %o5
.endif
 
/*
* Mark the CANRESTORE windows as OTHER windows.
*/
rdpr %canrestore, %l0
wrpr %l0, %otherwin
wrpr %g0, %canrestore
 
/*
* Switch to primary context 0.
*/
mov VA_PRIMARY_CONTEXT_REG, %l0
stxa %g0, [%l0] ASI_DMMU
rd %pc, %l0
flush %l0
 
.if NOT(\is_syscall)
ba 1f
nop
0:
save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
 
/*
* At this moment, we are using the kernel stack
* and have successfully allocated a register window.
*/
1:
.endif
/*
* Other window spills will go to the userspace window buffer
* and normal spills will go to the kernel stack.
*/
wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate
/*
* Copy arguments.
*/
mov %g1, %l0
.if NOT(\is_syscall)
mov %g2, %o0
.else
! store the syscall number on the stack as 7th argument
stx %g2, [%sp + STACK_WINDOW_SAVE_AREA_SIZE + STACK_BIAS + STACK_ARG6]
.endif
 
/*
* Save TSTATE, TPC and TNPC aside.
*/
rdpr %tstate, %g1
rdpr %tpc, %g2
rdpr %tnpc, %g3
rd %y, %g4
 
stx %g1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE]
stx %g2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC]
stx %g3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC]
 
/*
* Save the Y register.
* This register is deprecated according to SPARC V9 specification
* and is only present for backward compatibility with previous
* versions of the SPARC architecture.
* Surprisingly, gcc makes use of this register without a notice.
*/
stx %g4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y]
wrpr %g0, 0, %tl
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate
SAVE_GLOBALS
.if NOT(\is_syscall)
/*
* Call the higher-level handler and pass istate as second parameter.
*/
call %l0
add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
.else
/*
* Call the higher-level syscall handler and enable interrupts.
*/
call syscall_handler
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate
mov %o0, %i0 ! copy the value returned by the syscall
.endif
 
RESTORE_GLOBALS
rdpr %pstate, %l1 ! we must preserve the PEF bit
wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate
wrpr %g0, 1, %tl
/*
* Read TSTATE, TPC and TNPC from saved copy.
*/
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TSTATE], %g1
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TPC], %g2
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC], %g3
 
/*
* Copy PSTATE.PEF to the in-register copy of TSTATE.
*/
and %l1, PSTATE_PEF_BIT, %l1
sllx %l1, TSTATE_PSTATE_SHIFT, %l1
sethi %hi(TSTATE_PEF_BIT), %g4
andn %g1, %g4, %g1
or %g1, %l1, %g1
 
/*
* Restore TSTATE, TPC and TNPC from saved copies.
*/
wrpr %g1, 0, %tstate
wrpr %g2, 0, %tpc
wrpr %g3, 0, %tnpc
 
/*
* Restore Y.
*/
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_Y], %g4
wr %g4, %y
 
/*
* If OTHERWIN is zero, then all the userspace windows have been
* spilled to kernel memory (i.e. register window buffer). Moreover,
* if the scheduler was called in the meantime, all valid windows
* belonging to other threads were spilled by context_restore().
* If OTHERWIN is non-zero, then some userspace windows are still
* valid. Others might have been spilled. However, the CWP pointer
* needs no fixing because the scheduler had not been called.
*/
rdpr %otherwin, %l0
brnz %l0, 0f
nop
 
/*
* OTHERWIN == 0
*/
 
/*
* If TSTATE.CWP + 1 == CWP, then we still do not have to fix CWP.
*/
and %g1, TSTATE_CWP_MASK, %l0
inc %l0
and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS
rdpr %cwp, %l1
cmp %l0, %l1
bz 0f ! CWP is ok
nop
 
/*
* Fix CWP.
* In order to recapitulate, the input registers in the current
* window are the output registers of the window to which we want
* to restore. Because the fill trap fills only input and local
* registers of a window, we need to preserve those output
* registers manually.
*/
mov %sp, %g2
stx %i0, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0]
stx %i1, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1]
stx %i2, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2]
stx %i3, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3]
stx %i4, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4]
stx %i5, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5]
stx %i6, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6]
stx %i7, [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7]
wrpr %l0, 0, %cwp
mov %g2, %sp
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I0], %i0
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I1], %i1
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I2], %i2
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I3], %i3
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I4], %i4
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I5], %i5
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I6], %i6
ldx [%sp + PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_I7], %i7
 
/*
* OTHERWIN != 0 or fall-through from the OTHERWIN == 0 case.
* The CWP has already been restored to the value it had after the SAVE
* at the beginning of this function.
*/
0:
.if NOT(\is_syscall)
rdpr %tstate, %g1
andcc %g1, TSTATE_PRIV_BIT, %g0 ! if we are not returning to userspace...,
bnz 1f ! ...skip restoring userspace windows
nop
.endif
 
/*
* Spills and fills will be processed by the {spill,fill}_1_normal
* handlers.
*/
wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
 
/*
* Set primary context according to secondary context.
*/
wr %g0, ASI_DMMU, %asi
ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
rd %pc, %g1
flush %g1
rdpr %cwp, %g1
rdpr %otherwin, %g2
 
/*
* Skip all OTHERWIN windows and descend to the first window
* in the userspace window buffer.
*/
sub %g1, %g2, %g3
dec %g3
and %g3, NWINDOWS - 1, %g3
wrpr %g3, 0, %cwp
 
/*
* CWP is now in the window last saved in the userspace window buffer.
* Fill all windows stored in the buffer.
*/
clr %g4
0: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check
bz 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
nop
 
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7
ldx [%g7 + L0_OFFSET], %l0
ldx [%g7 + L1_OFFSET], %l1
ldx [%g7 + L2_OFFSET], %l2
ldx [%g7 + L3_OFFSET], %l3
ldx [%g7 + L4_OFFSET], %l4
ldx [%g7 + L5_OFFSET], %l5
ldx [%g7 + L6_OFFSET], %l6
ldx [%g7 + L7_OFFSET], %l7
ldx [%g7 + I0_OFFSET], %i0
ldx [%g7 + I1_OFFSET], %i1
ldx [%g7 + I2_OFFSET], %i2
ldx [%g7 + I3_OFFSET], %i3
ldx [%g7 + I4_OFFSET], %i4
ldx [%g7 + I5_OFFSET], %i5
ldx [%g7 + I6_OFFSET], %i6
ldx [%g7 + I7_OFFSET], %i7
 
dec %g3
and %g3, NWINDOWS - 1, %g3
wrpr %g3, 0, %cwp ! switch to the preceeding window
 
ba 0b
inc %g4
 
0:
/*
* Switch back to the proper current window and adjust
* OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN.
*/
wrpr %g1, 0, %cwp
add %g4, %g2, %g2
cmp %g2, NWINDOWS - 2
bg 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly
mov NWINDOWS - 2, %g1 ! use dealy slot for both cases
sub %g1, %g2, %g1
wrpr %g0, 0, %otherwin
wrpr %g1, 0, %cansave ! NWINDOWS - 2 - CANRESTORE
wrpr %g2, 0, %canrestore ! OTHERWIN + windows in the buffer
wrpr %g2, 0, %cleanwin ! avoid information leak
 
1:
restore
 
.if \is_syscall
done
.else
retry
.endif
 
/*
* We got here in order to avoid inconsistency of the window state registers.
* If the:
*
* save %g6, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
*
* instruction trapped and spilled a register window into the userspace
* window buffer, we have just restored NWINDOWS - 1 register windows.
* However, CANRESTORE can be only NWINDOW - 2 at most.
*
* The solution is to manually switch to (CWP - 1) mod NWINDOWS
* and set the window state registers so that:
*
* CANRESTORE = NWINDOWS - 2
* CLEANWIN = NWINDOWS - 2
* CANSAVE = 0
* OTHERWIN = 0
*
* The RESTORE instruction is therfore to be skipped.
*/
2:
wrpr %g0, 0, %otherwin
wrpr %g0, 0, %cansave
wrpr %g1, 0, %canrestore
wrpr %g1, 0, %cleanwin
 
rdpr %cwp, %g1
dec %g1
and %g1, NWINDOWS - 1, %g1
wrpr %g1, 0, %cwp ! CWP--
.if \is_syscall
done
.else
retry
.endif
 
.endm
 
.global preemptible_handler
preemptible_handler:
PREEMPTIBLE_HANDLER_TEMPLATE 0
 
.global trap_instruction_handler
trap_instruction_handler:
PREEMPTIBLE_HANDLER_TEMPLATE 1
/tags/0.4.0/kernel/arch/sparc64/src/trap/trap.c
0,0 → 1,54
/*
* Copyright (c) 2005 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 sparc64interrupt
* @{
*/
/** @file
*
*/
 
#include <arch/trap/trap.h>
#include <arch/trap/trap_table.h>
#include <arch/trap/regwin.h>
#include <arch/trap/exception.h>
#include <arch/trap/interrupt.h>
#include <arch/trap/mmu.h>
#include <arch/asm.h>
#include <memstr.h>
#include <debug.h>
#include <arch/types.h>
#include <arch/drivers/tick.h>
 
/** Initialize trap table. */
void trap_init(void)
{
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/trap/mmu.S
0,0 → 1,42
#
# 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.
#
 
/**
* @file
* @brief MMU trap handlers that do not fit into the trap table.
*/
 
.register %g2, #scratch
.register %g3, #scratch
 
.text
 
#include <arch/trap/mmu.h>
#include <arch/trap/trap_table.h>
#include <arch/regdef.h>
 
/tags/0.4.0/kernel/arch/sparc64/src/mm/tlb.c
0,0 → 1,628
/*
* Copyright (c) 2005 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/tlb.h>
#include <mm/tlb.h>
#include <mm/as.h>
#include <mm/asid.h>
#include <arch/mm/frame.h>
#include <arch/mm/page.h>
#include <arch/mm/mmu.h>
#include <arch/interrupt.h>
#include <interrupt.h>
#include <arch.h>
#include <print.h>
#include <arch/types.h>
#include <config.h>
#include <arch/trap/trap.h>
#include <arch/trap/exception.h>
#include <panic.h>
#include <arch/asm.h>
 
#ifdef CONFIG_TSB
#include <arch/mm/tsb.h>
#endif
 
static void dtlb_pte_copy(pte_t *, index_t, bool);
static void itlb_pte_copy(pte_t *, index_t);
static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
const char *);
static void do_fast_data_access_protection_fault(istate_t *,
tlb_tag_access_reg_t, const char *);
 
char *context_encoding[] = {
"Primary",
"Secondary",
"Nucleus",
"Reserved"
};
 
void tlb_arch_init(void)
{
/*
* Invalidate all non-locked DTLB and ITLB entries.
*/
tlb_invalidate_all();
 
/*
* Clear both SFSRs.
*/
dtlb_sfsr_write(0);
itlb_sfsr_write(0);
}
 
/** Insert privileged mapping into DMMU TLB.
*
* @param page Virtual page address.
* @param frame Physical frame address.
* @param pagesize Page size.
* @param locked True for permanent mappings, false otherwise.
* @param cacheable True if the mapping is cacheable, false otherwise.
*/
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
bool locked, bool cacheable)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
page_address_t pg;
frame_address_t fr;
 
pg.address = page;
fr.address = frame;
 
tag.context = ASID_KERNEL;
tag.vpn = pg.vpn;
 
dtlb_tag_access_write(tag.value);
 
data.value = 0;
data.v = true;
data.size = pagesize;
data.pfn = fr.pfn;
data.l = locked;
data.cp = cacheable;
#ifdef CONFIG_VIRT_IDX_DCACHE
data.cv = cacheable;
#endif /* CONFIG_VIRT_IDX_DCACHE */
data.p = true;
data.w = true;
data.g = false;
 
dtlb_data_in_write(data.value);
}
 
/** Copy PTE to TLB.
*
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param ro If true, the entry will be created read-only, regardless
* of its w field.
*/
void dtlb_pte_copy(pte_t *t, index_t index, bool ro)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
page_address_t pg;
frame_address_t fr;
 
pg.address = t->page + (index << MMU_PAGE_WIDTH);
fr.address = t->frame + (index << MMU_PAGE_WIDTH);
 
tag.value = 0;
tag.context = t->as->asid;
tag.vpn = pg.vpn;
 
dtlb_tag_access_write(tag.value);
 
data.value = 0;
data.v = true;
data.size = PAGESIZE_8K;
data.pfn = fr.pfn;
data.l = false;
data.cp = t->c;
#ifdef CONFIG_VIRT_IDX_DCACHE
data.cv = t->c;
#endif /* CONFIG_VIRT_IDX_DCACHE */
data.p = t->k; /* p like privileged */
data.w = ro ? false : t->w;
data.g = t->g;
 
dtlb_data_in_write(data.value);
}
 
/** Copy PTE to ITLB.
*
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
*/
void itlb_pte_copy(pte_t *t, index_t index)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
page_address_t pg;
frame_address_t fr;
 
pg.address = t->page + (index << MMU_PAGE_WIDTH);
fr.address = t->frame + (index << MMU_PAGE_WIDTH);
 
tag.value = 0;
tag.context = t->as->asid;
tag.vpn = pg.vpn;
itlb_tag_access_write(tag.value);
data.value = 0;
data.v = true;
data.size = PAGESIZE_8K;
data.pfn = fr.pfn;
data.l = false;
data.cp = t->c;
data.p = t->k; /* p like privileged */
data.w = false;
data.g = t->g;
itlb_data_in_write(data.value);
}
 
/** ITLB miss handler. */
void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
{
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
pte_t *t;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
if (t && PTE_EXECUTABLE(t)) {
/*
* The mapping was found in the software page hash table.
* Insert it into ITLB.
*/
t->a = true;
itlb_pte_copy(t, index);
#ifdef CONFIG_TSB
itsb_pte_copy(t, index);
#endif
page_table_unlock(AS, true);
} else {
/*
* Forward the page fault to the address space page fault
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
do_fast_instruction_access_mmu_miss_fault(istate,
__func__);
}
}
}
 
/** DTLB miss handler.
*
* Note that some faults (e.g. kernel faults) were already resolved by the
* low-level, assembly language part of the fast_data_access_mmu_miss handler.
*
* @param tag Content of the TLB Tag Access register as it existed
* when the trap happened. This is to prevent confusion
* created by clobbered Tag Access register during a nested
* DTLB miss.
* @param istate Interrupted state saved on the stack.
*/
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
{
uintptr_t va;
index_t index;
pte_t *t;
 
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
index = tag.vpn % MMU_PAGES_PER_PAGE;
 
if (tag.context == ASID_KERNEL) {
if (!tag.vpn) {
/* NULL access in kernel */
do_fast_data_access_mmu_miss_fault(istate, tag,
__func__);
}
do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
"kernel page fault.");
}
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
if (t) {
/*
* The mapping was found in the software page hash table.
* Insert it into DTLB.
*/
t->a = true;
dtlb_pte_copy(t, index, true);
#ifdef CONFIG_TSB
dtsb_pte_copy(t, index, true);
#endif
page_table_unlock(AS, true);
} else {
/*
* Forward the page fault to the address space page fault
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
do_fast_data_access_mmu_miss_fault(istate, tag,
__func__);
}
}
}
 
/** DTLB protection fault handler.
*
* @param tag Content of the TLB Tag Access register as it existed
* when the trap happened. This is to prevent confusion
* created by clobbered Tag Access register during a nested
* DTLB miss.
* @param istate Interrupted state saved on the stack.
*/
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
{
uintptr_t va;
index_t index;
pte_t *t;
 
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
if (t && PTE_WRITABLE(t)) {
/*
* The mapping was found in the software page hash table and is
* writable. Demap the old mapping and insert an updated mapping
* into DTLB.
*/
t->a = true;
t->d = true;
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
va + index * MMU_PAGE_SIZE);
dtlb_pte_copy(t, index, false);
#ifdef CONFIG_TSB
dtsb_pte_copy(t, index, false);
#endif
page_table_unlock(AS, true);
} else {
/*
* Forward the page fault to the address space page fault
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
do_fast_data_access_protection_fault(istate, tag,
__func__);
}
}
}
 
/** Print TLB entry (for debugging purposes).
*
* The diag field has been left out in order to make this function more generic
* (there is no diag field in US3 architeture).
*
* @param i TLB entry number
* @param t TLB entry tag
* @param d TLB entry data
*/
static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
{
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
"ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
}
 
#if defined (US)
 
/** Print contents of both TLBs. */
void tlb_print(void)
{
int i;
tlb_data_t d;
tlb_tag_read_reg_t t;
printf("I-TLB contents:\n");
for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
d.value = itlb_data_access_read(i);
t.value = itlb_tag_read_read(i);
print_tlb_entry(i, t, d);
}
 
printf("D-TLB contents:\n");
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
t.value = dtlb_tag_read_read(i);
print_tlb_entry(i, t, d);
}
}
 
#elif defined (US3)
 
/** Print contents of all TLBs. */
void tlb_print(void)
{
int i;
tlb_data_t d;
tlb_tag_read_reg_t t;
printf("TLB_ISMALL contents:\n");
for (i = 0; i < tlb_ismall_size(); i++) {
d.value = dtlb_data_access_read(TLB_ISMALL, i);
t.value = dtlb_tag_read_read(TLB_ISMALL, i);
print_tlb_entry(i, t, d);
}
printf("TLB_IBIG contents:\n");
for (i = 0; i < tlb_ibig_size(); i++) {
d.value = dtlb_data_access_read(TLB_IBIG, i);
t.value = dtlb_tag_read_read(TLB_IBIG, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DSMALL contents:\n");
for (i = 0; i < tlb_dsmall_size(); i++) {
d.value = dtlb_data_access_read(TLB_DSMALL, i);
t.value = dtlb_tag_read_read(TLB_DSMALL, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DBIG_1 contents:\n");
for (i = 0; i < tlb_dbig_size(); i++) {
d.value = dtlb_data_access_read(TLB_DBIG_0, i);
t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DBIG_2 contents:\n");
for (i = 0; i < tlb_dbig_size(); i++) {
d.value = dtlb_data_access_read(TLB_DBIG_1, i);
t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
print_tlb_entry(i, t, d);
}
}
 
#endif
 
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
const char *str)
{
fault_if_from_uspace(istate, "%s.", str);
dump_istate(istate);
panic("%s.", str);
}
 
void do_fast_data_access_mmu_miss_fault(istate_t *istate,
tlb_tag_access_reg_t tag, const char *str)
{
uintptr_t va;
 
va = tag.vpn << MMU_PAGE_WIDTH;
if (tag.context) {
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
tag.context);
}
dump_istate(istate);
printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
panic("%s.", str);
}
 
void do_fast_data_access_protection_fault(istate_t *istate,
tlb_tag_access_reg_t tag, const char *str)
{
uintptr_t va;
 
va = tag.vpn << MMU_PAGE_WIDTH;
 
if (tag.context) {
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
tag.context);
}
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
dump_istate(istate);
panic("%s.", str);
}
 
void dump_sfsr_and_sfar(void)
{
tlb_sfsr_reg_t sfsr;
uintptr_t sfar;
 
sfsr.value = dtlb_sfsr_read();
sfar = dtlb_sfar_read();
#if defined (US)
printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
"fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
sfsr.ow, sfsr.fv);
#elif defined (US3)
printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
"w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
#endif
printf("DTLB SFAR: address=%p\n", sfar);
dtlb_sfsr_write(0);
}
 
#if defined (US3)
/** Invalidates given TLB entry if and only if it is non-locked or global.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1,
* TLB_ISMALL, TLB_IBIG).
* @param entry Entry index within the given TLB.
*/
static void tlb_invalidate_entry(int tlb, index_t entry)
{
tlb_data_t d;
tlb_tag_read_reg_t t;
if (tlb == TLB_DSMALL || tlb == TLB_DBIG_0 || tlb == TLB_DBIG_1) {
d.value = dtlb_data_access_read(tlb, entry);
if (!d.l || d.g) {
t.value = dtlb_tag_read_read(tlb, entry);
d.v = false;
dtlb_tag_access_write(t.value);
dtlb_data_access_write(tlb, entry, d.value);
}
} else if (tlb == TLB_ISMALL || tlb == TLB_IBIG) {
d.value = itlb_data_access_read(tlb, entry);
if (!d.l || d.g) {
t.value = itlb_tag_read_read(tlb, entry);
d.v = false;
itlb_tag_access_write(t.value);
itlb_data_access_write(tlb, entry, d.value);
}
}
}
#endif
 
/** Invalidate all unlocked ITLB and DTLB entries. */
void tlb_invalidate_all(void)
{
int i;
/*
* Walk all ITLB and DTLB entries and remove all unlocked mappings.
*
* The kernel doesn't use global mappings so any locked global mappings
* found must have been created by someone else. Their only purpose now
* is to collide with proper mappings. Invalidate immediately. It should
* be safe to invalidate them as late as now.
*/
 
#if defined (US)
tlb_data_t d;
tlb_tag_read_reg_t t;
 
for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
d.value = itlb_data_access_read(i);
if (!d.l || d.g) {
t.value = itlb_tag_read_read(i);
d.v = false;
itlb_tag_access_write(t.value);
itlb_data_access_write(i, d.value);
}
}
 
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
if (!d.l || d.g) {
t.value = dtlb_tag_read_read(i);
d.v = false;
dtlb_tag_access_write(t.value);
dtlb_data_access_write(i, d.value);
}
}
 
#elif defined (US3)
 
for (i = 0; i < tlb_ismall_size(); i++)
tlb_invalidate_entry(TLB_ISMALL, i);
for (i = 0; i < tlb_ibig_size(); i++)
tlb_invalidate_entry(TLB_IBIG, i);
for (i = 0; i < tlb_dsmall_size(); i++)
tlb_invalidate_entry(TLB_DSMALL, i);
for (i = 0; i < tlb_dbig_size(); i++)
tlb_invalidate_entry(TLB_DBIG_0, i);
for (i = 0; i < tlb_dbig_size(); i++)
tlb_invalidate_entry(TLB_DBIG_1, i);
#endif
 
}
 
/** Invalidate all ITLB and DTLB entries that belong to specified ASID
* (Context).
*
* @param asid Address Space ID.
*/
void tlb_invalidate_asid(asid_t asid)
{
tlb_context_reg_t pc_save, ctx;
/* switch to nucleus because we are mapped by the primary context */
nucleus_enter();
ctx.v = pc_save.v = mmu_primary_context_read();
ctx.context = asid;
mmu_primary_context_write(ctx.v);
itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
mmu_primary_context_write(pc_save.v);
nucleus_leave();
}
 
/** Invalidate all ITLB and DTLB entries for specified page range in specified
* address space.
*
* @param asid Address Space ID.
* @param page First page which to sweep out from ITLB and DTLB.
* @param cnt Number of ITLB and DTLB entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
{
unsigned int i;
tlb_context_reg_t pc_save, ctx;
/* switch to nucleus because we are mapped by the primary context */
nucleus_enter();
ctx.v = pc_save.v = mmu_primary_context_read();
ctx.context = asid;
mmu_primary_context_write(ctx.v);
for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) {
itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
page + i * MMU_PAGE_SIZE);
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
page + i * MMU_PAGE_SIZE);
}
mmu_primary_context_write(pc_save.v);
nucleus_leave();
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/mm/as.c
0,0 → 1,224
/*
* 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/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
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/mm/cache.S
0,0 → 1,49
/*
* 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.
*/
 
#include <arch/arch.h>
#include <arch/mm/cache_spec.h>
 
#define DCACHE_TAG_SHIFT 2
 
.register %g2, #scratch
.register %g3, #scratch
 
/** Flush the whole D-cache. */
.global dcache_flush
dcache_flush:
set (DCACHE_SIZE - DCACHE_LINE_SIZE), %g1
stxa %g0, [%g1] ASI_DCACHE_TAG
0: membar #Sync
subcc %g1, DCACHE_LINE_SIZE, %g1
bnz,pt %xcc, 0b
stxa %g0, [%g1] ASI_DCACHE_TAG
membar #Sync
retl
! beware SF Erratum #51, do not put the MEMBAR here
nop
/tags/0.4.0/kernel/arch/sparc64/src/mm/tsb.c
0,0 → 1,176
/*
* 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/tsb.h>
#include <arch/mm/tlb.h>
#include <arch/mm/page.h>
#include <arch/barrier.h>
#include <mm/as.h>
#include <arch/types.h>
#include <macros.h>
#include <debug.h>
 
#define TSB_INDEX_MASK ((1 << (21 + 1 + TSB_SIZE - MMU_PAGE_WIDTH)) - 1)
 
/** Invalidate portion of TSB.
*
* We assume that the address space is already locked. Note that respective
* portions of both TSBs are invalidated at a time.
*
* @param as Address space.
* @param page First page to invalidate in TSB.
* @param pages Number of pages to invalidate. Value of (count_t) -1 means the
* whole TSB.
*/
void tsb_invalidate(as_t *as, uintptr_t page, count_t pages)
{
index_t i0, i;
count_t cnt;
ASSERT(as->arch.itsb && as->arch.dtsb);
i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
ASSERT(i0 < ITSB_ENTRY_COUNT && i0 < DTSB_ENTRY_COUNT);
 
if (pages == (count_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT)
cnt = ITSB_ENTRY_COUNT;
else
cnt = pages * 2;
for (i = 0; i < cnt; i++) {
as->arch.itsb[(i0 + i) & (ITSB_ENTRY_COUNT - 1)].tag.invalid =
true;
as->arch.dtsb[(i0 + i) & (DTSB_ENTRY_COUNT - 1)].tag.invalid =
true;
}
}
 
/** Copy software PTE to ITSB.
*
* @param t Software PTE.
* @param index Zero if lower 8K-subpage, one if higher 8K subpage.
*/
void itsb_pte_copy(pte_t *t, index_t index)
{
as_t *as;
tsb_entry_t *tsb;
index_t entry;
 
ASSERT(index <= 1);
as = t->as;
entry = ((t->page >> MMU_PAGE_WIDTH) + index) & TSB_INDEX_MASK;
ASSERT(entry < ITSB_ENTRY_COUNT);
tsb = &as->arch.itsb[entry];
 
/*
* We use write barriers to make sure that the TSB load
* won't use inconsistent data or that the fault will
* be repeated.
*/
 
tsb->tag.invalid = true; /* invalidate the entry
* (tag target has this
* set to 0) */
 
write_barrier();
 
tsb->tag.context = as->asid;
/* the shift is bigger than PAGE_WIDTH, do not bother with index */
tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
tsb->data.value = 0;
tsb->data.size = PAGESIZE_8K;
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
tsb->data.cp = t->c; /* cp as cache in phys.-idxed, c as cacheable */
tsb->data.p = t->k; /* p as privileged, k as kernel */
tsb->data.v = t->p; /* v as valid, p as present */
write_barrier();
tsb->tag.invalid = false; /* mark the entry as valid */
}
 
/** Copy software PTE to DTSB.
*
* @param t Software PTE.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param ro If true, the mapping is copied read-only.
*/
void dtsb_pte_copy(pte_t *t, index_t index, bool ro)
{
as_t *as;
tsb_entry_t *tsb;
index_t entry;
ASSERT(index <= 1);
 
as = t->as;
entry = ((t->page >> MMU_PAGE_WIDTH) + index) & TSB_INDEX_MASK;
ASSERT(entry < DTSB_ENTRY_COUNT);
tsb = &as->arch.dtsb[entry];
 
/*
* We use write barriers to make sure that the TSB load
* won't use inconsistent data or that the fault will
* be repeated.
*/
 
tsb->tag.invalid = true; /* invalidate the entry
* (tag target has this
* set to 0) */
 
write_barrier();
 
tsb->tag.context = as->asid;
/* the shift is bigger than PAGE_WIDTH, do not bother with index */
tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
tsb->data.value = 0;
tsb->data.size = PAGESIZE_8K;
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
tsb->data.cp = t->c;
#ifdef CONFIG_VIRT_IDX_DCACHE
tsb->data.cv = t->c;
#endif /* CONFIG_VIRT_IDX_DCACHE */
tsb->data.p = t->k; /* p as privileged */
tsb->data.w = ro ? false : t->w;
tsb->data.v = t->p;
write_barrier();
tsb->tag.invalid = false; /* mark the entry as valid */
}
 
/** @}
*/
 
/tags/0.4.0/kernel/arch/sparc64/src/mm/page.c
0,0 → 1,169
/*
* Copyright (c) 2005 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/page.h>
#include <arch/mm/tlb.h>
#include <genarch/mm/page_ht.h>
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <bitops.h>
#include <debug.h>
#include <align.h>
#include <config.h>
 
#ifdef CONFIG_SMP
/** Entries locked in DTLB of BSP.
*
* Application processors need to have the same locked entries in their DTLBs as
* the bootstrap processor.
*/
static struct {
uintptr_t virt_page;
uintptr_t phys_page;
int pagesize_code;
} bsp_locked_dtlb_entry[DTLB_MAX_LOCKED_ENTRIES];
 
/** Number of entries in bsp_locked_dtlb_entry array. */
static count_t bsp_locked_dtlb_entries = 0;
#endif /* CONFIG_SMP */
 
/** Perform sparc64 specific initialization of paging. */
void page_arch_init(void)
{
if (config.cpu_active == 1) {
page_mapping_operations = &ht_mapping_operations;
} else {
 
#ifdef CONFIG_SMP
unsigned int i;
 
/*
* Copy locked DTLB entries from the BSP.
*/
for (i = 0; i < bsp_locked_dtlb_entries; i++) {
dtlb_insert_mapping(bsp_locked_dtlb_entry[i].virt_page,
bsp_locked_dtlb_entry[i].phys_page,
bsp_locked_dtlb_entry[i].pagesize_code, true,
false);
}
#endif
 
}
}
 
/** Map memory-mapped device into virtual memory.
*
* So far, only DTLB is used to map devices into memory. Chances are that there
* will be only a limited amount of devices that the kernel itself needs to
* lock in DTLB.
*
* @param physaddr Physical address of the page where the device is located.
* Must be at least page-aligned.
* @param size Size of the device's registers. Must not exceed 4M and must
* include extra space caused by the alignment.
*
* @return Virtual address of the page where the device is mapped.
*/
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
unsigned int order;
unsigned int i;
 
ASSERT(config.cpu_active == 1);
 
struct {
int pagesize_code;
size_t increment;
count_t count;
} sizemap[] = {
{ PAGESIZE_8K, 0, 1 }, /* 8K */
{ PAGESIZE_8K, MMU_PAGE_SIZE, 2 }, /* 16K */
{ PAGESIZE_8K, MMU_PAGE_SIZE, 4 }, /* 32K */
{ PAGESIZE_64K, 0, 1}, /* 64K */
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 2 }, /* 128K */
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 4 }, /* 256K */
{ PAGESIZE_512K, 0, 1 }, /* 512K */
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 2 }, /* 1M */
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 4 }, /* 2M */
{ PAGESIZE_4M, 0, 1 }, /* 4M */
{ PAGESIZE_4M, 512 * MMU_PAGE_SIZE, 2 } /* 8M */
};
ASSERT(ALIGN_UP(physaddr, MMU_PAGE_SIZE) == physaddr);
ASSERT(size <= 8 * 1024 * 1024);
if (size <= MMU_FRAME_SIZE)
order = 0;
else
order = (fnzb64(size - 1) + 1) - MMU_FRAME_WIDTH;
 
/*
* Use virtual addresses that are beyond the limit of physical memory.
* Thus, the physical address space will not be wasted by holes created
* by frame_alloc().
*/
ASSERT(PA2KA(last_frame));
uintptr_t virtaddr = ALIGN_UP(PA2KA(last_frame),
1 << (order + FRAME_WIDTH));
last_frame = ALIGN_UP(KA2PA(virtaddr) + size,
1 << (order + FRAME_WIDTH));
for (i = 0; i < sizemap[order].count; i++) {
/*
* First, insert the mapping into DTLB.
*/
dtlb_insert_mapping(virtaddr + i * sizemap[order].increment,
physaddr + i * sizemap[order].increment,
sizemap[order].pagesize_code, true, false);
#ifdef CONFIG_SMP
/*
* Second, save the information about the mapping for APs.
*/
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].virt_page =
virtaddr + i * sizemap[order].increment;
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].phys_page =
physaddr + i * sizemap[order].increment;
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].pagesize_code =
sizemap[order].pagesize_code;
bsp_locked_dtlb_entries++;
#endif
}
return virtaddr;
}
 
/** @}
*/
 
/tags/0.4.0/kernel/arch/sparc64/src/mm/frame.c
0,0 → 1,86
/*
* Copyright (c) 2005 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/frame.h>
#include <mm/frame.h>
#include <arch/boot/boot.h>
#include <arch/types.h>
#include <config.h>
#include <align.h>
#include <macros.h>
 
uintptr_t last_frame = NULL;
 
/** Create memory zones according to information stored in bootinfo.
*
* Walk the bootinfo memory map and create frame zones according to it.
*/
void frame_arch_init(void)
{
unsigned int i;
pfn_t confdata;
 
if (config.cpu_active == 1) {
for (i = 0; i < bootinfo.memmap.count; i++) {
uintptr_t start = bootinfo.memmap.zones[i].start;
size_t size = bootinfo.memmap.zones[i].size;
 
/*
* The memmap is created by HelenOS boot loader.
* It already contains no holes.
*/
 
confdata = ADDR2PFN(start);
if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0))))
confdata = ADDR2PFN(KA2PA(PFN2ADDR(2)));
zone_create(ADDR2PFN(start),
SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)),
confdata, 0);
last_frame = max(last_frame, start + ALIGN_UP(size,
FRAME_SIZE));
}
 
/*
* On sparc64, physical memory can start on a non-zero address.
* The generic frame_init() only marks PFN 0 as not free, so we
* must mark the physically first frame not free explicitly
* here, no matter what is its address.
*/
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
}
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/ddi/ddi.c
0,0 → 1,55
/*
* 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 sparc64ddi
* @{
*/
/** @file
*/
 
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Starting I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
return 0;
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/cpu/cpu.c
0,0 → 1,189
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#include <arch/cpu_family.h>
#include <cpu.h>
#include <arch.h>
#include <genarch/ofw/ofw_tree.h>
#include <arch/drivers/tick.h>
#include <print.h>
#include <arch/cpu_node.h>
 
/**
* Finds out the clock frequency of the current CPU.
*
* @param node node representing the current CPU in the OFW tree
* @return clock frequency if "node" is the current CPU and no error
* occurs, -1 if "node" is not the current CPU or on error
*/
static int find_cpu_frequency(ofw_tree_node_t *node)
{
ofw_tree_property_t *prop;
uint32_t mid;
 
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
prop = ofw_tree_getprop(node, "upa-portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "cpuid");
if (prop && prop->value) {
mid = *((uint32_t *) prop->value);
if (mid == CPU->arch.mid) {
prop = ofw_tree_getprop(node, "clock-frequency");
if (prop && prop->value) {
return *((uint32_t *) prop->value);
}
}
}
return -1;
}
 
/** Perform sparc64 specific initialization of the processor structure for the
* current processor.
*/
void cpu_arch_init(void)
{
ofw_tree_node_t *node;
uint32_t clock_frequency = 0;
CPU->arch.mid = read_mid();
/*
* Detect processor frequency.
*/
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
while (node) {
int f = find_cpu_frequency(node);
if (f != -1)
clock_frequency = (uint32_t) f;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
}
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
int f;
f = find_cpu_frequency(
ofw_tree_find_child(node, "cpu@0"));
if (f != -1)
clock_frequency = (uint32_t) f;
f = find_cpu_frequency(
ofw_tree_find_child(node, "cpu@1"));
if (f != -1)
clock_frequency = (uint32_t) f;
node = ofw_tree_find_peer_by_name(node, "cmp");
}
}
CPU->arch.clock_frequency = clock_frequency;
tick_init();
}
 
/** Read version information from the current processor. */
void cpu_identify(void)
{
CPU->arch.ver.value = ver_read();
}
 
/** Print version information for a processor.
*
* This function is called by the bootstrap processor.
*
* @param m Processor structure of the CPU for which version information is to
* be printed.
*/
void cpu_print_report(cpu_t *m)
{
char *manuf, *impl;
 
switch (m->arch.ver.manuf) {
case MANUF_FUJITSU:
manuf = "Fujitsu";
break;
case MANUF_ULTRASPARC:
manuf = "UltraSPARC";
break;
case MANUF_SUN:
manuf = "Sun";
break;
default:
manuf = "Unknown";
break;
}
switch (CPU->arch.ver.impl) {
case IMPL_ULTRASPARCI:
impl = "UltraSPARC I";
break;
case IMPL_ULTRASPARCII:
impl = "UltraSPARC II";
break;
case IMPL_ULTRASPARCII_I:
impl = "UltraSPARC IIi";
break;
case IMPL_ULTRASPARCII_E:
impl = "UltraSPARC IIe";
break;
case IMPL_ULTRASPARCIII:
impl = "UltraSPARC III";
break;
case IMPL_ULTRASPARCIII_PLUS:
impl = "UltraSPARC III+";
break;
case IMPL_ULTRASPARCIII_I:
impl = "UltraSPARC IIIi";
break;
case IMPL_ULTRASPARCIV:
impl = "UltraSPARC IV";
break;
case IMPL_ULTRASPARCIV_PLUS:
impl = "UltraSPARC IV+";
break;
case IMPL_SPARC64V:
impl = "SPARC 64V";
break;
default:
impl = "Unknown";
break;
}
 
printf("cpu%d: manuf=%s, impl=%s, mask=%d (%d MHz)\n", m->id, manuf,
impl, m->arch.ver.mask, m->arch.clock_frequency / 1000000);
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/start.S
0,0 → 1,396
#
# Copyright (c) 2005 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.
#
 
#include <arch/arch.h>
#include <arch/cpu.h>
#include <arch/regdef.h>
#include <arch/boot/boot.h>
#include <arch/stack.h>
 
#include <arch/mm/mmu.h>
#include <arch/mm/tlb.h>
#include <arch/mm/tte.h>
 
#ifdef CONFIG_SMP
#include <arch/context_offset.h>
#endif
 
.register %g2, #scratch
.register %g3, #scratch
 
.section K_TEXT_START, "ax"
 
#define BSP_FLAG 1
 
/*
* 2^PHYSMEM_ADDR_SIZE is the size of the physical address space on
* a given processor.
*/
#if defined (US)
#define PHYSMEM_ADDR_SIZE 41
#elif defined (US3)
#define PHYSMEM_ADDR_SIZE 43
#endif
 
/*
* Here is where the kernel is passed control from the boot loader.
*
* The registers are expected to be in this state:
* - %o0 starting address of physical memory + bootstrap processor flag
* bits 63...1: physical memory starting address / 2
* bit 0: non-zero on BSP processor, zero on AP processors
* - %o1 bootinfo structure address (BSP only)
* - %o2 bootinfo structure size (BSP only)
*
* Moreover, we depend on boot having established the following environment:
* - TLBs are on
* - identity mapping for the kernel image
*/
 
.global kernel_image_start
kernel_image_start:
mov BSP_FLAG, %l0
and %o0, %l0, %l7 ! l7 <= bootstrap processor?
andn %o0, %l0, %l6 ! l6 <= start of physical memory
 
! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base.
srlx %l6, 13, %l5
! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5
/*
* Setup basic runtime environment.
*/
 
wrpr %g0, NWINDOWS - 2, %cansave ! set maximum saveable windows
wrpr %g0, 0, %canrestore ! get rid of windows we will
! never need again
wrpr %g0, 0, %otherwin ! make sure the window state is
! consistent
wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent needless clean_window
! traps for kernel
wrpr %g0, 0, %wstate ! use default spill/fill trap
 
wrpr %g0, 0, %tl ! TL = 0, primary context
! register is used
 
wrpr %g0, PSTATE_PRIV_BIT, %pstate ! disable interrupts and disable
! 32-bit address masking
 
wrpr %g0, 0, %pil ! intialize %pil
 
/*
* Switch to kernel trap table.
*/
sethi %hi(trap_table), %g1
wrpr %g1, %lo(trap_table), %tba
 
/*
* Take over the DMMU by installing locked TTE entry identically
* mapping the first 4M of memory.
*
* In case of DMMU, no FLUSH instructions need to be issued. Because of
* that, the old DTLB contents can be demapped pretty straightforwardly
* and without causing any traps.
*/
 
wr %g0, ASI_DMMU, %asi
 
#define SET_TLB_DEMAP_CMD(r1, context_id) \
set (TLB_DEMAP_CONTEXT << TLB_DEMAP_TYPE_SHIFT) | (context_id << \
TLB_DEMAP_CONTEXT_SHIFT), %r1
! demap context 0
SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
stxa %g0, [%g1] ASI_DMMU_DEMAP
membar #Sync
 
#define SET_TLB_TAG(r1, context) \
set VMA | (context << TLB_TAG_ACCESS_CONTEXT_SHIFT), %r1
 
! write DTLB tag
SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
stxa %g1, [VA_DMMU_TAG_ACCESS] %asi
membar #Sync
 
#ifdef CONFIG_VIRT_IDX_DCACHE
#define TTE_LOW_DATA(imm) (TTE_CP | TTE_CV | TTE_P | LMA | (imm))
#else /* CONFIG_VIRT_IDX_DCACHE */
#define TTE_LOW_DATA(imm) (TTE_CP | TTE_P | LMA | (imm))
#endif /* CONFIG_VIRT_IDX_DCACHE */
 
#define SET_TLB_DATA(r1, r2, imm) \
set TTE_LOW_DATA(imm), %r1; \
or %r1, %l5, %r1; \
mov PAGESIZE_4M, %r2; \
sllx %r2, TTE_SIZE_SHIFT, %r2; \
or %r1, %r2, %r1; \
mov 1, %r2; \
sllx %r2, TTE_V_SHIFT, %r2; \
or %r1, %r2, %r1;
! write DTLB data and install the kernel mapping
SET_TLB_DATA(g1, g2, TTE_L | TTE_W) ! use non-global mapping
stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG
membar #Sync
 
/*
* Because we cannot use global mappings (because we want to have
* separate 64-bit address spaces for both the kernel and the
* userspace), we prepare the identity mapping also in context 1. This
* step is required by the code installing the ITLB mapping.
*/
! write DTLB tag of context 1 (i.e. MEM_CONTEXT_TEMP)
SET_TLB_TAG(g1, MEM_CONTEXT_TEMP)
stxa %g1, [VA_DMMU_TAG_ACCESS] %asi
membar #Sync
 
! write DTLB data and install the kernel mapping in context 1
SET_TLB_DATA(g1, g2, TTE_W) ! use non-global mapping
stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG
membar #Sync
/*
* Now is time to take over the IMMU. Unfortunatelly, it cannot be done
* as easily as the DMMU, because the IMMU is mapping the code it
* executes.
*
* [ Note that brave experiments with disabling the IMMU and using the
* DMMU approach failed after a dozen of desparate days with only little
* success. ]
*
* The approach used here is inspired from OpenBSD. First, the kernel
* creates IMMU mapping for itself in context 1 (MEM_CONTEXT_TEMP) and
* switches to it. Context 0 (MEM_CONTEXT_KERNEL) can be demapped
* afterwards and replaced with the kernel permanent mapping. Finally,
* the kernel switches back to context 0 and demaps context 1.
*
* Moreover, the IMMU requires use of the FLUSH instructions. But that
* is OK because we always use operands with addresses already mapped by
* the taken over DTLB.
*/
set kernel_image_start, %g5
! write ITLB tag of context 1
SET_TLB_TAG(g1, MEM_CONTEXT_TEMP)
mov VA_DMMU_TAG_ACCESS, %g2
stxa %g1, [%g2] ASI_IMMU
flush %g5
 
! write ITLB data and install the temporary mapping in context 1
SET_TLB_DATA(g1, g2, 0) ! use non-global mapping
stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG
flush %g5
! switch to context 1
mov MEM_CONTEXT_TEMP, %g1
stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
flush %g5
! demap context 0
SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS)
stxa %g0, [%g1] ASI_IMMU_DEMAP
flush %g5
! write ITLB tag of context 0
SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL)
mov VA_DMMU_TAG_ACCESS, %g2
stxa %g1, [%g2] ASI_IMMU
flush %g5
 
! write ITLB data and install the permanent kernel mapping in context 0
SET_TLB_DATA(g1, g2, TTE_L) ! use non-global mapping
stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG
flush %g5
 
! enter nucleus - using context 0
wrpr %g0, 1, %tl
 
! demap context 1
SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_PRIMARY)
stxa %g0, [%g1] ASI_IMMU_DEMAP
flush %g5
! set context 0 in the primary context register
stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!!
flush %g5
! leave nucleus - using primary context, i.e. context 0
wrpr %g0, 0, %tl
 
brz %l7, 1f ! skip if you are not the bootstrap CPU
nop
 
/*
* Save physmem_base for use by the mm subsystem.
* %l6 contains starting physical address
*/
sethi %hi(physmem_base), %l4
stx %l6, [%l4 + %lo(physmem_base)]
 
/*
* Precompute kernel 8K TLB data template.
* %l5 contains starting physical address
* bits [(PHYSMEM_ADDR_SIZE - 1):13]
*/
sethi %hi(kernel_8k_tlb_data_template), %l4
ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3
or %l3, %l5, %l3
stx %l3, [%l4 + %lo(kernel_8k_tlb_data_template)]
 
/*
* Flush D-Cache.
*/
call dcache_flush
nop
 
/*
* So far, we have not touched the stack.
* It is a good idea to set the kernel stack to a known state now.
*/
sethi %hi(temporary_boot_stack), %sp
or %sp, %lo(temporary_boot_stack), %sp
sub %sp, STACK_BIAS, %sp
 
sethi %hi(bootinfo), %o0
call memcpy ! copy bootinfo
or %o0, %lo(bootinfo), %o0
 
call arch_pre_main
nop
call main_bsp
nop
 
/* Not reached. */
 
0:
ba 0b
nop
 
 
1:
#ifdef CONFIG_SMP
/*
* Determine the width of the MID and save its mask to %g3. The width
* is
* * 5 for US and US-IIIi,
* * 10 for US3 except US-IIIi.
*/
#if defined(US)
mov 0x1f, %g3
#elif defined(US3)
mov 0x3ff, %g3
rdpr %ver, %g2
sllx %g2, 16, %g2
srlx %g2, 48, %g2
cmp %g2, IMPL_ULTRASPARCIII_I
move %xcc, 0x1f, %g3
#endif
 
/*
* Read MID from the processor.
*/
ldxa [%g0] ASI_ICBUS_CONFIG, %g1
srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1
and %g1, %g3, %g1
 
/*
* Active loop for APs until the BSP picks them up. A processor cannot
* leave the loop until the global variable 'waking_up_mid' equals its
* MID.
*/
set waking_up_mid, %g2
2:
ldx [%g2], %g3
cmp %g3, %g1
bne 2b
nop
 
/*
* Configure stack for the AP.
* The AP is expected to use the stack saved
* in the ctx global variable.
*/
set ctx, %g1
add %g1, OFFSET_SP, %g1
ldx [%g1], %o6
 
call main_ap
nop
 
/* Not reached. */
#endif
0:
ba 0b
nop
 
 
.section K_DATA_START, "aw", @progbits
 
/*
* Create small stack to be used by the bootstrap processor. It is going to be
* used only for a very limited period of time, but we switch to it anyway,
* just to be sure we are properly initialized.
*/
 
#define INITIAL_STACK_SIZE 1024
 
.align STACK_ALIGNMENT
.space INITIAL_STACK_SIZE
.align STACK_ALIGNMENT
temporary_boot_stack:
.space STACK_WINDOW_SAVE_AREA_SIZE
 
 
.data
 
.align 8
.global physmem_base ! copy of the physical memory base address
physmem_base:
.quad 0
 
/*
* This variable is used by the fast_data_MMU_miss trap handler. In runtime, it
* is further modified to reflect the starting address of physical memory.
*/
.global kernel_8k_tlb_data_template
kernel_8k_tlb_data_template:
#ifdef CONFIG_VIRT_IDX_DCACHE
.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \
TTE_CV | TTE_P | TTE_W)
#else /* CONFIG_VIRT_IDX_DCACHE */
.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \
TTE_P | TTE_W)
#endif /* CONFIG_VIRT_IDX_DCACHE */
 
/tags/0.4.0/kernel/arch/sparc64/src/proc/thread.c
0,0 → 1,83
/*
* 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 sparc64proc
* @{
*/
/** @file
*/
 
#include <proc/thread.h>
#include <arch/proc/thread.h>
#include <mm/slab.h>
#include <arch/trap/regwin.h>
#include <align.h>
 
void thr_constructor_arch(thread_t *t)
{
/*
* Allocate memory for uspace_window_buffer.
*/
t->arch.uspace_window_buffer = NULL;
}
 
void thr_destructor_arch(thread_t *t)
{
if (t->arch.uspace_window_buffer) {
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
/*
* Mind the possible alignment of the userspace window buffer
* belonging to a killed thread.
*/
free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT));
}
}
 
void thread_create_arch(thread_t *t)
{
if ((t->flags & THREAD_FLAG_USPACE) && (!t->arch.uspace_window_buffer))
{
/*
* The thread needs userspace window buffer and the object
* returned from the slab allocator doesn't have any.
*/
t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0);
} else {
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
 
/*
* Mind the possible alignment of the userspace window buffer
* belonging to a killed thread.
*/
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf,
UWB_ASIZE);
}
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/proc/scheduler.c
0,0 → 1,83
/*
* 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 sparc64proc
* @{
*/
/** @file
*/
 
#include <proc/scheduler.h>
#include <proc/thread.h>
#include <arch.h>
#include <arch/asm.h>
#include <arch/stack.h>
 
/** Perform sparc64 specific tasks needed before the new task is run. */
void before_task_runs_arch(void)
{
}
 
/** Perform sparc64 specific steps before scheduling a thread.
*
* For userspace threads, initialize reserved global registers in the alternate
* and interrupt sets.
*/
void before_thread_runs_arch(void)
{
if ((THREAD->flags & THREAD_FLAG_USPACE)) {
/*
* Write kernel stack address to %g6 of the alternate and
* interrupt global sets.
*
* Write pointer to the last item in the userspace window buffer
* to %g7 in the alternate set. Write to the interrupt %g7 is
* not necessary because:
* - spill traps operate only in the alternate global set,
* - preemptible trap handler switches to alternate globals
* before it explicitly uses %g7.
*/
uint64_t sp = (uintptr_t) THREAD->kstack + STACK_SIZE -
(STACK_BIAS + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT));
write_to_ig_g6(sp);
write_to_ag_g6(sp);
write_to_ag_g7((uintptr_t) THREAD->arch.uspace_window_buffer);
}
}
 
/** Perform sparc64 specific steps before a thread stops running. */
void after_thread_ran_arch(void)
{
if ((THREAD->flags & THREAD_FLAG_USPACE)) {
/* sample the state of the userspace window buffer */
THREAD->arch.uspace_window_buffer = (uint8_t *) read_from_ag_g7();
}
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/asm.S
0,0 → 1,311
#
# Copyright (c) 2005 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.
#
 
#include <arch/arch.h>
#include <arch/stack.h>
#include <arch/regdef.h>
#include <arch/mm/mmu.h>
 
.text
 
.register %g2, #scratch
.register %g3, #scratch
 
/*
* This is the assembly language version of our _memcpy() generated by gcc.
*/
.global memcpy
memcpy:
mov %o0, %o3 ! save dst
add %o1, 7, %g1
and %g1, -8, %g1
cmp %o1, %g1
be,pn %xcc, 3f
add %o0, 7, %g1
mov 0, %g3
0:
brz,pn %o2, 2f
mov 0, %g2
1:
ldub [%g3 + %o1], %g1
add %g2, 1, %g2
cmp %o2, %g2
stb %g1, [%g3 + %o0]
bne,pt %xcc, 1b
mov %g2, %g3
2:
jmp %o7 + 8 ! exit point
mov %o3, %o0
3:
and %g1, -8, %g1
cmp %o0, %g1
bne,pt %xcc, 0b
mov 0, %g3
srlx %o2, 3, %g4
brz,pn %g4, 5f
mov 0, %g5
4:
sllx %g3, 3, %g2
add %g5, 1, %g3
ldx [%o1 + %g2], %g1
mov %g3, %g5
cmp %g4, %g3
bne,pt %xcc, 4b
stx %g1, [%o0 + %g2]
5:
and %o2, 7, %o2
brz,pn %o2, 2b
sllx %g4, 3, %g1
mov 0, %g2
add %g1, %o0, %o0
add %g1, %o1, %g4
mov 0, %g3
6:
ldub [%g2 + %g4], %g1
stb %g1, [%g2 + %o0]
add %g3, 1, %g2
cmp %o2, %g2
bne,pt %xcc, 6b
mov %g2, %g3
 
jmp %o7 + 8 ! exit point
mov %o3, %o0
 
/*
* Almost the same as memcpy() except the loads are from userspace.
*/
.global memcpy_from_uspace
memcpy_from_uspace:
mov %o0, %o3 ! save dst
add %o1, 7, %g1
and %g1, -8, %g1
cmp %o1, %g1
be,pn %xcc, 3f
add %o0, 7, %g1
mov 0, %g3
0:
brz,pn %o2, 2f
mov 0, %g2
1:
lduba [%g3 + %o1] ASI_AIUS, %g1
add %g2, 1, %g2
cmp %o2, %g2
stb %g1, [%g3 + %o0]
bne,pt %xcc, 1b
mov %g2, %g3
2:
jmp %o7 + 8 ! exit point
mov %o3, %o0
3:
and %g1, -8, %g1
cmp %o0, %g1
bne,pt %xcc, 0b
mov 0, %g3
srlx %o2, 3, %g4
brz,pn %g4, 5f
mov 0, %g5
4:
sllx %g3, 3, %g2
add %g5, 1, %g3
ldxa [%o1 + %g2] ASI_AIUS, %g1
mov %g3, %g5
cmp %g4, %g3
bne,pt %xcc, 4b
stx %g1, [%o0 + %g2]
5:
and %o2, 7, %o2
brz,pn %o2, 2b
sllx %g4, 3, %g1
mov 0, %g2
add %g1, %o0, %o0
add %g1, %o1, %g4
mov 0, %g3
6:
lduba [%g2 + %g4] ASI_AIUS, %g1
stb %g1, [%g2 + %o0]
add %g3, 1, %g2
cmp %o2, %g2
bne,pt %xcc, 6b
mov %g2, %g3
 
jmp %o7 + 8 ! exit point
mov %o3, %o0
 
/*
* Almost the same as memcpy() except the stores are to userspace.
*/
.global memcpy_to_uspace
memcpy_to_uspace:
mov %o0, %o3 ! save dst
add %o1, 7, %g1
and %g1, -8, %g1
cmp %o1, %g1
be,pn %xcc, 3f
add %o0, 7, %g1
mov 0, %g3
0:
brz,pn %o2, 2f
mov 0, %g2
1:
ldub [%g3 + %o1], %g1
add %g2, 1, %g2
cmp %o2, %g2
stba %g1, [%g3 + %o0] ASI_AIUS
bne,pt %xcc, 1b
mov %g2, %g3
2:
jmp %o7 + 8 ! exit point
mov %o3, %o0
3:
and %g1, -8, %g1
cmp %o0, %g1
bne,pt %xcc, 0b
mov 0, %g3
srlx %o2, 3, %g4
brz,pn %g4, 5f
mov 0, %g5
4:
sllx %g3, 3, %g2
add %g5, 1, %g3
ldx [%o1 + %g2], %g1
mov %g3, %g5
cmp %g4, %g3
bne,pt %xcc, 4b
stxa %g1, [%o0 + %g2] ASI_AIUS
5:
and %o2, 7, %o2
brz,pn %o2, 2b
sllx %g4, 3, %g1
mov 0, %g2
add %g1, %o0, %o0
add %g1, %o1, %g4
mov 0, %g3
6:
ldub [%g2 + %g4], %g1
stba %g1, [%g2 + %o0] ASI_AIUS
add %g3, 1, %g2
cmp %o2, %g2
bne,pt %xcc, 6b
mov %g2, %g3
 
jmp %o7 + 8 ! exit point
mov %o3, %o0
 
.global memcpy_from_uspace_failover_address
.global memcpy_to_uspace_failover_address
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
jmp %o7 + 8 ! exit point
mov %g0, %o0 ! return 0 on failure
 
.global memsetb
memsetb:
b _memsetb
nop
 
 
.macro WRITE_ALTERNATE_REGISTER reg, bit
rdpr %pstate, %g1 ! save PSTATE.PEF
wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
mov %o0, \reg
wrpr %g0, PSTATE_PRIV_BIT, %pstate
retl
wrpr %g1, 0, %pstate ! restore PSTATE.PEF
.endm
 
.macro READ_ALTERNATE_REGISTER reg, bit
rdpr %pstate, %g1 ! save PSTATE.PEF
wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
mov \reg, %o0
wrpr %g0, PSTATE_PRIV_BIT, %pstate
retl
wrpr %g1, 0, %pstate ! restore PSTATE.PEF
.endm
 
.global write_to_ag_g6
write_to_ag_g6:
WRITE_ALTERNATE_REGISTER %g6, PSTATE_AG_BIT
 
.global write_to_ag_g7
write_to_ag_g7:
WRITE_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
 
.global write_to_ig_g6
write_to_ig_g6:
WRITE_ALTERNATE_REGISTER %g6, PSTATE_IG_BIT
 
.global read_from_ag_g7
read_from_ag_g7:
READ_ALTERNATE_REGISTER %g7, PSTATE_AG_BIT
 
 
/** Switch to userspace.
*
* %o0 Userspace entry address.
* %o1 Userspace stack pointer address.
* %o2 Userspace address of uarg structure.
*/
.global switch_to_userspace
switch_to_userspace:
save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
flushw
wrpr %g0, 0, %cleanwin ! avoid information leak
 
mov %i2, %o0 ! uarg
xor %o1, %o1, %o1 ! %o1 is defined to hold pcb_ptr
! set it to 0
 
clr %i2
clr %i3
clr %i4
clr %i5
clr %i6
 
wrpr %g0, 1, %tl ! enforce mapping via nucleus
 
rdpr %cwp, %g1
wrpr %g1, TSTATE_IE_BIT, %tstate
wrpr %i0, 0, %tnpc
/*
* Set primary context according to secondary context.
* Secondary context has been already installed by
* higher-level functions.
*/
wr %g0, ASI_DMMU, %asi
ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
flush %i7
 
/*
* Spills and fills will be handled by the userspace handlers.
*/
wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
done ! jump to userspace
 
/tags/0.4.0/kernel/arch/sparc64/src/context.S
0,0 → 1,63
#
# Copyright (c) 2005 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.
#
 
#include <arch/context_offset.h>
 
/**
* Both context_save_arch() and context_restore_arch() are
* leaf-optimized procedures. This kind of optimization
* is very important and prevents any implicit window
* spill/fill/clean traps in these very core kernel
* functions.
*/
#include <arch/context_offset.h>
 
.text
 
.global context_save_arch
.global context_restore_arch
 
context_save_arch:
CONTEXT_SAVE_ARCH_CORE %o0
retl
mov 1, %o0 ! context_save_arch returns 1
 
context_restore_arch:
#
# Flush all active windows.
# This is essential, because CONTEXT_LOAD overwrites
# %sp of CWP - 1 with the value written to %fp of CWP.
# Flushing all active windows mitigates this problem
# as CWP - 1 becomes the overlap window.
#
flushw
CONTEXT_RESTORE_ARCH_CORE %o0
retl
xor %o0, %o0, %o0 ! context_restore_arch returns 0
/tags/0.4.0/kernel/arch/sparc64/src/fpu_context.c
0,0 → 1,178
/*
* 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 sparc64
* @{
*/
/** @file
*
*/
 
#include <fpu_context.h>
#include <arch/register.h>
#include <arch/asm.h>
 
void fpu_context_save(fpu_context_t *fctx)
{
asm volatile (
"std %%f0, %0\n"
"std %%f2, %1\n"
"std %%f4, %2\n"
"std %%f6, %3\n"
"std %%f8, %4\n"
"std %%f10, %5\n"
"std %%f12, %6\n"
"std %%f14, %7\n"
"std %%f16, %8\n"
"std %%f18, %9\n"
"std %%f20, %10\n"
"std %%f22, %11\n"
"std %%f24, %12\n"
"std %%f26, %13\n"
"std %%f28, %14\n"
"std %%f30, %15\n"
: "=m" (fctx->d[0]), "=m" (fctx->d[1]), "=m" (fctx->d[2]), "=m" (fctx->d[3]),
"=m" (fctx->d[4]), "=m" (fctx->d[5]), "=m" (fctx->d[6]), "=m" (fctx->d[7]),
"=m" (fctx->d[8]), "=m" (fctx->d[9]), "=m" (fctx->d[10]), "=m" (fctx->d[11]),
"=m" (fctx->d[12]), "=m" (fctx->d[13]), "=m" (fctx->d[14]), "=m" (fctx->d[15])
);
 
/*
* We need to split loading of the floating-point registers because
* GCC (4.1.1) can't handle more than 30 operands in one asm statement.
*/
asm volatile (
"std %%f32, %0\n"
"std %%f34, %1\n"
"std %%f36, %2\n"
"std %%f38, %3\n"
"std %%f40, %4\n"
"std %%f42, %5\n"
"std %%f44, %6\n"
"std %%f46, %7\n"
"std %%f48, %8\n"
"std %%f50, %9\n"
"std %%f52, %10\n"
"std %%f54, %11\n"
"std %%f56, %12\n"
"std %%f58, %13\n"
"std %%f60, %14\n"
"std %%f62, %15\n"
: "=m" (fctx->d[16]), "=m" (fctx->d[17]), "=m" (fctx->d[18]), "=m" (fctx->d[19]),
"=m" (fctx->d[20]), "=m" (fctx->d[21]), "=m" (fctx->d[22]), "=m" (fctx->d[23]),
"=m" (fctx->d[24]), "=m" (fctx->d[25]), "=m" (fctx->d[26]), "=m" (fctx->d[27]),
"=m" (fctx->d[28]), "=m" (fctx->d[29]), "=m" (fctx->d[30]), "=m" (fctx->d[31])
);
asm volatile ("stx %%fsr, %0\n" : "=m" (fctx->fsr));
}
 
void fpu_context_restore(fpu_context_t *fctx)
{
asm volatile (
"ldd %0, %%f0\n"
"ldd %1, %%f2\n"
"ldd %2, %%f4\n"
"ldd %3, %%f6\n"
"ldd %4, %%f8\n"
"ldd %5, %%f10\n"
"ldd %6, %%f12\n"
"ldd %7, %%f14\n"
"ldd %8, %%f16\n"
"ldd %9, %%f18\n"
"ldd %10, %%f20\n"
"ldd %11, %%f22\n"
"ldd %12, %%f24\n"
"ldd %13, %%f26\n"
"ldd %14, %%f28\n"
"ldd %15, %%f30\n"
:
: "m" (fctx->d[0]), "m" (fctx->d[1]), "m" (fctx->d[2]), "m" (fctx->d[3]),
"m" (fctx->d[4]), "m" (fctx->d[5]), "m" (fctx->d[6]), "m" (fctx->d[7]),
"m" (fctx->d[8]), "m" (fctx->d[9]), "m" (fctx->d[10]), "m" (fctx->d[11]),
"m" (fctx->d[12]), "m" (fctx->d[13]), "m" (fctx->d[14]), "m" (fctx->d[15])
);
/*
* We need to split loading of the floating-point registers because
* GCC (4.1.1) can't handle more than 30 operands in one asm statement.
*/
asm volatile (
"ldd %0, %%f32\n"
"ldd %1, %%f34\n"
"ldd %2, %%f36\n"
"ldd %3, %%f38\n"
"ldd %4, %%f40\n"
"ldd %5, %%f42\n"
"ldd %6, %%f44\n"
"ldd %7, %%f46\n"
"ldd %8, %%f48\n"
"ldd %9, %%f50\n"
"ldd %10, %%f52\n"
"ldd %11, %%f54\n"
"ldd %12, %%f56\n"
"ldd %13, %%f58\n"
"ldd %14, %%f60\n"
"ldd %15, %%f62\n"
:
: "m" (fctx->d[16]), "m" (fctx->d[17]), "m" (fctx->d[18]), "m" (fctx->d[19]),
"m" (fctx->d[20]), "m" (fctx->d[21]), "m" (fctx->d[22]), "m" (fctx->d[23]),
"m" (fctx->d[24]), "m" (fctx->d[25]), "m" (fctx->d[26]), "m" (fctx->d[27]),
"m" (fctx->d[28]), "m" (fctx->d[29]), "m" (fctx->d[30]), "m" (fctx->d[31])
);
asm volatile ("ldx %0, %%fsr\n" : : "m" (fctx->fsr));
}
 
void fpu_enable(void)
{
pstate_reg_t pstate;
pstate.value = pstate_read();
pstate.pef = true;
pstate_write(pstate.value);
}
 
void fpu_disable(void)
{
pstate_reg_t pstate;
pstate.value = pstate_read();
pstate.pef = false;
pstate_write(pstate.value);
}
 
void fpu_init(void)
{
fpu_enable();
}
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/src/panic.S
0,0 → 1,40
#
# Copyright (c) 2005 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.
#
 
.text
 
#include <arch/stack.h>
 
.global panic_printf
panic_printf:
call printf
nop
call halt
nop
/* Not reached. */
 
/tags/0.4.0/kernel/arch/sparc64/src/dummy.s
0,0 → 1,46
#
# Copyright (c) 2005 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.
#
 
.text
 
.global cpu_sleep
.global sys_tls_set
 
.global dummy
 
cpu_sleep: ! not supported by architecture
sys_tls_set: ! not needed on architecture
 
dummy:
retl
nop
 
.global cpu_halt
cpu_halt:
b cpu_halt
nop
/tags/0.4.0/kernel/arch/sparc64/include/types.h
0,0 → 1,92
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_TYPES_H_
#define KERN_sparc64_TYPES_H_
 
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef signed long int64_t;
 
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
 
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
 
typedef uint64_t ipl_t;
 
typedef uint64_t unative_t;
typedef int64_t native_t;
 
typedef uintptr_t ioport_t;
 
/**< Formats for uintptr_t, size_t, count_t and index_t */
#define PRIp "llx"
#define PRIs "llu"
#define PRIc "llu"
#define PRIi "llu"
 
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
#define PRId8 "d"
#define PRId16 "d"
#define PRId32 "d"
#define PRId64 "lld"
#define PRIdn "lld"
 
#define PRIu8 "u"
#define PRIu16 "u"
#define PRIu32 "u"
#define PRIu64 "llu"
#define PRIun "llu"
 
#define PRIx8 "x"
#define PRIx16 "x"
#define PRIx32 "x"
#define PRIx64 "llx"
#define PRIxn "llx"
 
typedef uint8_t asi_t;
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/scr.h
0,0 → 1,57
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_SCR_H_
#define KERN_sparc64_SCR_H_
 
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
 
typedef enum {
SCR_UNKNOWN,
SCR_ATYFB,
SCR_FFB,
SCR_CGSIX,
SCR_XVR
} scr_type_t;
 
extern scr_type_t scr_type;
 
extern void scr_init(ofw_tree_node_t *node);
extern void scr_redraw(void);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/sgcn.h
0,0 → 1,126
/*
* Copyright (c) 2008 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_SGCN_H_
#define KERN_sparc64_SGCN_H_
 
#include <arch/types.h>
 
/* number of bytes in the TOC magic, including the terminating '\0' */
#define TOC_MAGIC_BYTES 8
 
/* number of bytes in the TOC key, including the terminating '\0' */
#define TOC_KEY_SIZE 8
 
/* maximum number of entries in the SRAM table of contents */
#define MAX_TOC_ENTRIES 32
 
/* number of bytes in the SGCN buffer magic, including the terminating '\0' */
#define SGCN_MAGIC_BYTES 4
 
/**
* Entry in the SRAM table of contents. Describes one segment of the SRAM
* which serves a particular purpose (e.g. OBP serial console, Solaris serial
* console, Solaris mailbox,...).
*/
typedef struct {
/** key (e.g. "OBPCONS", "SOLCONS", "SOLMBOX",...) */
char key[TOC_KEY_SIZE];
/** size of the segment in bytes */
uint32_t size;
/** offset of the segment within SRAM */
uint32_t offset;
} __attribute ((packed)) toc_entry_t;
 
/**
* SRAM table of contents. Describes all segments within the SRAM.
*/
typedef struct {
/** hard-wired to "TOCSRAM" */
char magic[TOC_MAGIC_BYTES];
/** we don't need this */
char unused[8];
/** TOC entries */
toc_entry_t keys[MAX_TOC_ENTRIES];
} __attribute__ ((packed)) iosram_toc_t;
 
/**
* SGCN buffer header. It is placed at the very beginning of the SGCN
* buffer.
*/
typedef struct {
/** hard-wired to "CON" */
char magic[SGCN_MAGIC_BYTES];
/** we don't need this */
char unused[8];
/** offset within the SGCN buffer of the input buffer start */
uint32_t in_begin;
/** offset within the SGCN buffer of the input buffer end */
uint32_t in_end;
/** offset within the SGCN buffer of the input buffer read pointer */
uint32_t in_rdptr;
/** offset within the SGCN buffer of the input buffer write pointer */
uint32_t in_wrptr;
 
/** offset within the SGCN buffer of the output buffer start */
uint32_t out_begin;
/** offset within the SGCN buffer of the output buffer end */
uint32_t out_end;
/** offset within the SGCN buffer of the output buffer read pointer */
uint32_t out_rdptr;
/** offset within the SGCN buffer of the output buffer write pointer */
uint32_t out_wrptr;
} __attribute__ ((packed)) sgcn_buffer_header_t;
 
void sgcn_grab(void);
void sgcn_release(void);
void sgcn_poll(void);
void sgcn_init(void);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/kbd.h
0,0 → 1,55
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_KBD_H_
#define KERN_sparc64_KBD_H_
 
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
 
typedef enum {
KBD_UNKNOWN,
KBD_Z8530,
KBD_NS16550,
KBD_SGCN
} kbd_type_t;
 
extern kbd_type_t kbd_type;
 
extern void kbd_init(ofw_tree_node_t *node);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/pci.h
0,0 → 1,71
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_PCI_H_
#define KERN_sparc64_PCI_H_
 
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
#include <arch/arch.h>
#include <arch/asm.h>
 
typedef enum pci_model pci_model_t;
typedef struct pci pci_t;
typedef struct pci_operations pci_operations_t;
 
enum pci_model {
PCI_UNKNOWN,
PCI_SABRE,
PCI_PSYCHO
};
 
struct pci_operations {
void (* enable_interrupt)(pci_t *, int);
void (* clear_interrupt)(pci_t *, int);
};
 
struct pci {
pci_model_t model;
pci_operations_t *op;
volatile uint64_t *reg; /**< Registers including interrupt registers. */
};
 
extern pci_t *pci_init(ofw_tree_node_t *);
extern void pci_enable_interrupt(pci_t *, int);
extern void pci_clear_interrupt(void *, int);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/fhc.h
0,0 → 1,54
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_FHC_H_
#define KERN_sparc64_FHC_H_
 
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
 
typedef struct {
volatile uint32_t *uart_imap;
} fhc_t;
 
extern fhc_t *central_fhc;
 
extern fhc_t *fhc_init(ofw_tree_node_t *);
extern void fhc_enable_interrupt(fhc_t *, int);
extern void fhc_clear_interrupt(void *, int);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/ns16550.h
0,0 → 1,42
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_NS16550_H_
#define KERN_sparc64_NS16550_H_
 
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/z8530.h
0,0 → 1,140
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_Z8530_H_
#define KERN_sparc64_Z8530_H_
 
#include <arch/types.h>
#include <arch/drivers/kbd.h>
 
#define Z8530_CHAN_A 4
#define Z8530_CHAN_B 0
 
#define WR0 0
#define WR1 1
#define WR2 2
#define WR3 3
#define WR4 4
#define WR5 5
#define WR6 6
#define WR7 7
#define WR8 8
#define WR9 9
#define WR10 10
#define WR11 11
#define WR12 12
#define WR13 13
#define WR14 14
#define WR15 15
 
#define RR0 0
#define RR1 1
#define RR2 2
#define RR3 3
#define RR8 8
#define RR10 10
#define RR12 12
#define RR13 13
#define RR14 14
#define RR15 15
 
/* Write Register 0 */
#define WR0_TX_IP_RST (0x5<<3) /** Reset pending TX interrupt. */
#define WR0_ERR_RST (0x6<<3)
 
/* Write Register 1 */
#define WR1_RID (0x0<<3) /** Receive Interrupts Disabled. */
#define WR1_RIFCSC (0x1<<3) /** Receive Interrupt on First Character or Special Condition. */
#define WR1_IARCSC (0x2<<3) /** Interrupt on All Receive Characters or Special Conditions. */
#define WR1_RISC (0x3<<3) /** Receive Interrupt on Special Condition. */
#define WR1_PISC (0x1<<2) /** Parity Is Special Condition. */
 
/* Write Register 3 */
#define WR3_RX_ENABLE (0x1<<0) /** Rx Enable. */
#define WR3_RX8BITSCH (0x3<<6) /** 8-bits per character. */
 
/* Write Register 9 */
#define WR9_MIE (0x1<<3) /** Master Interrupt Enable. */
 
/* Read Register 0 */
#define RR0_RCA (0x1<<0) /** Receive Character Available. */
 
/** Structure representing the z8530 device. */
typedef struct {
devno_t devno;
volatile uint8_t *reg; /** Memory mapped registers of the z8530. */
} z8530_t;
 
static inline void z8530_write(z8530_t *dev, index_t chan, uint8_t reg, uint8_t val)
{
/*
* Registers 8-15 will automatically issue the Point High
* command as their bit 3 is 1.
*/
dev->reg[WR0+chan] = reg; /* select register */
dev->reg[WR0+chan] = val; /* write value */
}
 
static inline void z8530_write_a(z8530_t *dev, uint8_t reg, uint8_t val)
{
z8530_write(dev, Z8530_CHAN_A, reg, val);
}
static inline void z8530_write_b(z8530_t *dev, uint8_t reg, uint8_t val)
{
z8530_write(dev, Z8530_CHAN_B, reg, val);
}
 
static inline uint8_t z8530_read(z8530_t *dev, index_t chan, uint8_t reg)
{
/*
* Registers 8-15 will automatically issue the Point High
* command as their bit 3 is 1.
*/
dev->reg[WR0+chan] = reg; /* select register */
return dev->reg[WR0+chan];
}
 
static inline uint8_t z8530_read_a(z8530_t *dev, uint8_t reg)
{
return z8530_read(dev, Z8530_CHAN_A, reg);
}
static inline uint8_t z8530_read_b(z8530_t *dev, uint8_t reg)
{
return z8530_read(dev, Z8530_CHAN_B, reg);
}
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/tick.h
0,0 → 1,46
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_TICK_H_
#define KERN_sparc64_TICK_H_
 
#include <arch/interrupt.h>
 
extern void tick_init(void);
extern void tick_interrupt(int n, istate_t *istate);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/drivers/fb.h
0,0 → 1,41
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_FB_H_
#define KERN_sparc64_FB_H_
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/barrier.h
0,0 → 1,121
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_BARRIER_H_
#define KERN_sparc64_BARRIER_H_
 
/*
* Our critical section barriers are prepared for the weakest RMO memory model.
*/
#define CS_ENTER_BARRIER() \
asm volatile ( \
"membar #LoadLoad | #LoadStore\n" \
::: "memory" \
)
#define CS_LEAVE_BARRIER() \
asm volatile ( \
"membar #StoreStore\n" \
"membar #LoadStore\n" \
::: "memory" \
)
 
#define memory_barrier() \
asm volatile ("membar #LoadLoad | #StoreStore\n" ::: "memory")
#define read_barrier() \
asm volatile ("membar #LoadLoad\n" ::: "memory")
#define write_barrier() \
asm volatile ("membar #StoreStore\n" ::: "memory")
 
#define flush(a) \
asm volatile ("flush %0\n" :: "r" ((a)) : "memory")
 
/** Flush Instruction pipeline. */
static inline void flush_pipeline(void)
{
/*
* The FLUSH instruction takes address parameter.
* As such, it may trap if the address is not found in DTLB.
*
* The entire kernel text is mapped by a locked ITLB and
* DTLB entries. Therefore, when this function is called,
* the %o7 register will always be in the range mapped by
* DTLB.
*/
asm volatile ("flush %o7\n");
}
 
/** Memory Barrier instruction. */
static inline void membar(void)
{
asm volatile ("membar #Sync\n");
}
 
#if defined (US)
 
#define smc_coherence(a) \
{ \
write_barrier(); \
flush((a)); \
}
 
#define FLUSH_INVAL_MIN 4
#define smc_coherence_block(a, l) \
{ \
unsigned long i; \
write_barrier(); \
for (i = 0; i < (l); i += FLUSH_INVAL_MIN) \
flush((void *)(a) + i); \
}
 
#elif defined (US3)
 
#define smc_coherence(a) \
{ \
write_barrier(); \
flush_pipeline(); \
}
 
#define smc_coherence_block(a, l) \
{ \
write_barrier(); \
flush_pipeline(); \
}
 
#endif /* defined(US3) */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/regdef.h
0,0 → 1,67
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_REGDEF_H_
#define KERN_sparc64_REGDEF_H_
 
#define PSTATE_IE_BIT (1 << 1)
#define PSTATE_AM_BIT (1 << 3)
 
#define PSTATE_AG_BIT (1 << 0)
#define PSTATE_IG_BIT (1 << 11)
#define PSTATE_MG_BIT (1 << 10)
 
#define PSTATE_PRIV_BIT (1 << 2)
#define PSTATE_PEF_BIT (1 << 4)
 
#define TSTATE_PSTATE_SHIFT 8
#define TSTATE_PRIV_BIT (PSTATE_PRIV_BIT << TSTATE_PSTATE_SHIFT)
#define TSTATE_IE_BIT (PSTATE_IE_BIT << TSTATE_PSTATE_SHIFT)
#define TSTATE_PEF_BIT (PSTATE_PEF_BIT << TSTATE_PSTATE_SHIFT)
 
#define TSTATE_CWP_MASK 0x1f
 
#define WSTATE_NORMAL(n) (n)
#define WSTATE_OTHER(n) ((n) << 3)
 
/*
* The following definitions concern the UPA_CONFIG register on US and the
* FIREPLANE_CONFIG register on US3.
*/
#define ICBUS_CONFIG_MID_SHIFT 17
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/cpu_node.h
0,0 → 1,58
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CPU_NODE_H_
#define KERN_sparc64_CPU_NODE_H_
 
#include <genarch/ofw/ofw_tree.h>
 
 
/** Finds the parent node of all the CPU nodes (nodes named "cpu" or "cmp").
*
* Depending on the machine type (and possibly the OFW version), CPUs can be
* at "/" or at "/ssm@0,0".
*/
static inline ofw_tree_node_t *cpus_parent(void)
{
ofw_tree_node_t *parent;
parent = ofw_tree_find_child(ofw_tree_lookup("/"), "ssm@0,0");
if (parent == NULL)
parent = ofw_tree_lookup("/");
return parent;
}
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/arch.h
0,0 → 1,51
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/**
* @file
* @brief Various sparc64-specific macros.
*/
 
#ifndef KERN_sparc64_ARCH_H_
#define KERN_sparc64_ARCH_H_
 
#define ASI_AIUP 0x10 /** Access to primary context with user privileges. */
#define ASI_AIUS 0x11 /** Access to secondary context with user privileges. */
#define ASI_NUCLEUS_QUAD_LDD 0x24 /** ASI for 16-byte atomic loads. */
#define ASI_DCACHE_TAG 0x47 /** ASI D-Cache Tag. */
#define ASI_ICBUS_CONFIG 0x4a /** ASI of the UPA_CONFIG/FIREPLANE_CONFIG register. */
 
#define NWINDOWS 8 /** Number of register window sets. */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/asm.h
0,0 → 1,446
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_ASM_H_
#define KERN_sparc64_ASM_H_
 
#include <arch/arch.h>
#include <arch/types.h>
#include <typedefs.h>
#include <align.h>
#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.
*/
static inline uint64_t pstate_read(void)
{
uint64_t v;
asm volatile ("rdpr %%pstate, %0\n" : "=r" (v));
return v;
}
 
/** Write Processor State register.
*
* @param v New value of PSTATE register.
*/
static inline void pstate_write(uint64_t v)
{
asm volatile ("wrpr %0, %1, %%pstate\n" : : "r" (v), "i" (0));
}
 
/** Read TICK_compare Register.
*
* @return Value of TICK_comapre register.
*/
static inline uint64_t tick_compare_read(void)
{
uint64_t v;
asm volatile ("rd %%tick_cmpr, %0\n" : "=r" (v));
return v;
}
 
/** Write TICK_compare Register.
*
* @param v New value of TICK_comapre register.
*/
static inline void tick_compare_write(uint64_t v)
{
asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
}
 
/** Read STICK_compare Register.
*
* @return Value of STICK_compare register.
*/
static inline uint64_t stick_compare_read(void)
{
uint64_t v;
asm volatile ("rd %%asr25, %0\n" : "=r" (v));
return v;
}
 
/** Write STICK_compare Register.
*
* @param v New value of STICK_comapre register.
*/
static inline void stick_compare_write(uint64_t v)
{
asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0));
}
 
/** Read TICK Register.
*
* @return Value of TICK register.
*/
static inline uint64_t tick_read(void)
{
uint64_t v;
asm volatile ("rdpr %%tick, %0\n" : "=r" (v));
return v;
}
 
/** Write TICK Register.
*
* @param v New value of TICK register.
*/
static inline void tick_write(uint64_t v)
{
asm volatile ("wrpr %0, %1, %%tick\n" : : "r" (v), "i" (0));
}
 
/** Read FPRS Register.
*
* @return Value of FPRS register.
*/
static inline uint64_t fprs_read(void)
{
uint64_t v;
asm volatile ("rd %%fprs, %0\n" : "=r" (v));
return v;
}
 
/** Write FPRS Register.
*
* @param v New value of FPRS register.
*/
static inline void fprs_write(uint64_t v)
{
asm volatile ("wr %0, %1, %%fprs\n" : : "r" (v), "i" (0));
}
 
/** Read SOFTINT Register.
*
* @return Value of SOFTINT register.
*/
static inline uint64_t softint_read(void)
{
uint64_t v;
 
asm volatile ("rd %%softint, %0\n" : "=r" (v));
 
return v;
}
 
/** Write SOFTINT Register.
*
* @param v New value of SOFTINT register.
*/
static inline void softint_write(uint64_t v)
{
asm volatile ("wr %0, %1, %%softint\n" : : "r" (v), "i" (0));
}
 
/** Write CLEAR_SOFTINT Register.
*
* Bits set in CLEAR_SOFTINT register will be cleared in SOFTINT register.
*
* @param v New value of CLEAR_SOFTINT register.
*/
static inline void clear_softint_write(uint64_t v)
{
asm volatile ("wr %0, %1, %%clear_softint\n" : : "r" (v), "i" (0));
}
 
/** Write SET_SOFTINT Register.
*
* Bits set in SET_SOFTINT register will be set in SOFTINT register.
*
* @param v New value of SET_SOFTINT register.
*/
static inline void set_softint_write(uint64_t v)
{
asm volatile ("wr %0, %1, %%set_softint\n" : : "r" (v), "i" (0));
}
 
/** Enable interrupts.
*
* Enable interrupts and return previous
* value of IPL.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_enable(void) {
pstate_reg_t pstate;
uint64_t value;
value = pstate_read();
pstate.value = value;
pstate.ie = true;
pstate_write(pstate.value);
return (ipl_t) value;
}
 
/** Disable interrupts.
*
* Disable interrupts and return previous
* value of IPL.
*
* @return Old interrupt priority level.
*/
static inline ipl_t interrupts_disable(void) {
pstate_reg_t pstate;
uint64_t value;
value = pstate_read();
pstate.value = value;
pstate.ie = false;
pstate_write(pstate.value);
return (ipl_t) value;
}
 
/** Restore interrupt priority level.
*
* Restore IPL.
*
* @param ipl Saved interrupt priority level.
*/
static inline void interrupts_restore(ipl_t ipl) {
pstate_reg_t pstate;
pstate.value = pstate_read();
pstate.ie = ((pstate_reg_t) ipl).ie;
pstate_write(pstate.value);
}
 
/** Return interrupt priority level.
*
* Return IPL.
*
* @return Current interrupt priority level.
*/
static inline ipl_t interrupts_read(void) {
return (ipl_t) pstate_read();
}
 
/** Return base address of current stack.
*
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*/
static inline uintptr_t get_stack_base(void)
{
uintptr_t unbiased_sp;
asm volatile ("add %%sp, %1, %0\n" : "=r" (unbiased_sp) : "i" (STACK_BIAS));
return ALIGN_DOWN(unbiased_sp, STACK_SIZE);
}
 
/** Read Version Register.
*
* @return Value of VER register.
*/
static inline uint64_t ver_read(void)
{
uint64_t v;
asm volatile ("rdpr %%ver, %0\n" : "=r" (v));
return v;
}
 
/** Read Trap Program Counter register.
*
* @return Current value in TPC.
*/
static inline uint64_t tpc_read(void)
{
uint64_t v;
asm volatile ("rdpr %%tpc, %0\n" : "=r" (v));
return v;
}
 
/** Read Trap Level register.
*
* @return Current value in TL.
*/
static inline uint64_t tl_read(void)
{
uint64_t v;
asm volatile ("rdpr %%tl, %0\n" : "=r" (v));
return v;
}
 
/** Read Trap Base Address register.
*
* @return Current value in TBA.
*/
static inline uint64_t tba_read(void)
{
uint64_t v;
asm volatile ("rdpr %%tba, %0\n" : "=r" (v));
return v;
}
 
/** Write Trap Base Address register.
*
* @param v New value of TBA.
*/
static inline void tba_write(uint64_t v)
{
asm volatile ("wrpr %0, %1, %%tba\n" : : "r" (v), "i" (0));
}
 
/** Load uint64_t from alternate space.
*
* @param asi ASI determining the alternate space.
* @param va Virtual address within the ASI.
*
* @return Value read from the virtual address in the specified address space.
*/
static inline uint64_t asi_u64_read(asi_t asi, uintptr_t va)
{
uint64_t v;
asm volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" ((unsigned) asi));
return v;
}
 
/** Store uint64_t to alternate space.
*
* @param asi ASI determining the alternate space.
* @param va Virtual address within the ASI.
* @param v Value to be written.
*/
static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
{
asm volatile ("stxa %0, [%1] %2\n" : : "r" (v), "r" (va), "i" ((unsigned) asi) : "memory");
}
 
/** Flush all valid register windows to memory. */
static inline void flushw(void)
{
asm volatile ("flushw\n");
}
 
/** Switch to nucleus by setting TL to 1. */
static inline void nucleus_enter(void)
{
asm volatile ("wrpr %g0, 1, %tl\n");
}
 
/** Switch from nucleus by setting TL to 0. */
static inline void nucleus_leave(void)
{
asm volatile ("wrpr %g0, %g0, %tl\n");
}
 
extern void cpu_halt(void);
extern void cpu_sleep(void);
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);
extern void write_to_ag_g7(uint64_t val);
extern void write_to_ig_g6(uint64_t val);
 
extern void switch_to_userspace(uint64_t pc, uint64_t sp, uint64_t uarg);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/trap/interrupt.h
0,0 → 1,139
/*
* Copyright (c) 2005 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 sparc64interrupt
* @{
*/
/**
* @file
* @brief This file contains interrupt vector trap handler.
*/
 
#ifndef KERN_sparc64_TRAP_INTERRUPT_H_
#define KERN_sparc64_TRAP_INTERRUPT_H_
 
#include <arch/trap/trap_table.h>
#include <arch/stack.h>
 
/* IMAP register bits */
#define IGN_MASK 0x7c0
#define INO_MASK 0x1f
#define IMAP_V_MASK (1ULL << 31)
 
#define IGN_SHIFT 6
 
 
/* Interrupt ASI registers. */
#define ASI_INTR_W 0x77
#define ASI_INTR_DISPATCH_STATUS 0x48
#define ASI_INTR_R 0x7f
#define ASI_INTR_RECEIVE 0x49
 
/* VA's used with ASI_INTR_W register. */
#if defined (US)
#define ASI_UDB_INTR_W_DATA_0 0x40
#define ASI_UDB_INTR_W_DATA_1 0x50
#define ASI_UDB_INTR_W_DATA_2 0x60
#elif defined (US3)
#define VA_INTR_W_DATA_0 0x40
#define VA_INTR_W_DATA_1 0x48
#define VA_INTR_W_DATA_2 0x50
#define VA_INTR_W_DATA_3 0x58
#define VA_INTR_W_DATA_4 0x60
#define VA_INTR_W_DATA_5 0x68
#define VA_INTR_W_DATA_6 0x80
#define VA_INTR_W_DATA_7 0x88
#endif
#define VA_INTR_W_DISPATCH 0x70
 
/* VA's used with ASI_INTR_R register. */
#if defined(US)
#define ASI_UDB_INTR_R_DATA_0 0x40
#define ASI_UDB_INTR_R_DATA_1 0x50
#define ASI_UDB_INTR_R_DATA_2 0x60
#elif defined (US3)
#define VA_INTR_R_DATA_0 0x40
#define VA_INTR_R_DATA_1 0x48
#define VA_INTR_R_DATA_2 0x50
#define VA_INTR_R_DATA_3 0x58
#define VA_INTR_R_DATA_4 0x60
#define VA_INTR_R_DATA_5 0x68
#define VA_INTR_R_DATA_6 0x80
#define VA_INTR_R_DATA_7 0x88
#endif
 
/* Shifts in the Interrupt Vector Dispatch virtual address. */
#define INTR_VEC_DISPATCH_MID_SHIFT 14
 
/* Bits in the Interrupt Dispatch Status register. */
#define INTR_DISPATCH_STATUS_NACK 0x2
#define INTR_DISPATCH_STATUS_BUSY 0x1
 
#define TT_INTERRUPT_LEVEL_1 0x41
#define TT_INTERRUPT_LEVEL_2 0x42
#define TT_INTERRUPT_LEVEL_3 0x43
#define TT_INTERRUPT_LEVEL_4 0x44
#define TT_INTERRUPT_LEVEL_5 0x45
#define TT_INTERRUPT_LEVEL_6 0x46
#define TT_INTERRUPT_LEVEL_7 0x47
#define TT_INTERRUPT_LEVEL_8 0x48
#define TT_INTERRUPT_LEVEL_9 0x49
#define TT_INTERRUPT_LEVEL_10 0x4a
#define TT_INTERRUPT_LEVEL_11 0x4b
#define TT_INTERRUPT_LEVEL_12 0x4c
#define TT_INTERRUPT_LEVEL_13 0x4d
#define TT_INTERRUPT_LEVEL_14 0x4e
#define TT_INTERRUPT_LEVEL_15 0x4f
 
#define TT_INTERRUPT_VECTOR_TRAP 0x60
 
#define INTERRUPT_LEVEL_N_HANDLER_SIZE TRAP_TABLE_ENTRY_SIZE
#define INTERRUPT_VECTOR_TRAP_HANDLER_SIZE TRAP_TABLE_ENTRY_SIZE
 
#ifdef __ASM__
.macro INTERRUPT_LEVEL_N_HANDLER n
mov \n - 1, %g2
PREEMPTIBLE_HANDLER exc_dispatch
.endm
 
.macro INTERRUPT_VECTOR_TRAP_HANDLER
PREEMPTIBLE_HANDLER interrupt
.endm
#endif /* __ASM__ */
 
#ifndef __ASM__
 
#include <arch/interrupt.h>
 
extern void interrupt(int n, istate_t *istate);
#endif /* !def __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/trap/regwin.h
0,0 → 1,237
/*
* Copyright (c) 2005 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 sparc64interrupt
* @{
*/
/**
* @file
* @brief This file contains register window trap handlers.
*/
 
#ifndef KERN_sparc64_REGWIN_H_
#define KERN_sparc64_REGWIN_H_
 
#include <arch/stack.h>
#include <arch/arch.h>
#include <align.h>
 
#define TT_CLEAN_WINDOW 0x24
#define TT_SPILL_0_NORMAL 0x80 /* kernel spills */
#define TT_SPILL_1_NORMAL 0x84 /* userspace spills */
#define TT_SPILL_2_NORMAL 0x88 /* spills to userspace window buffer */
#define TT_SPILL_0_OTHER 0xa0 /* spills to userspace window buffer */
#define TT_FILL_0_NORMAL 0xc0 /* kernel fills */
#define TT_FILL_1_NORMAL 0xc4 /* userspace fills */
 
#define REGWIN_HANDLER_SIZE 128
 
#define CLEAN_WINDOW_HANDLER_SIZE REGWIN_HANDLER_SIZE
#define SPILL_HANDLER_SIZE REGWIN_HANDLER_SIZE
#define FILL_HANDLER_SIZE REGWIN_HANDLER_SIZE
 
/* Window Save Area offsets. */
#define L0_OFFSET 0
#define L1_OFFSET 8
#define L2_OFFSET 16
#define L3_OFFSET 24
#define L4_OFFSET 32
#define L5_OFFSET 40
#define L6_OFFSET 48
#define L7_OFFSET 56
#define I0_OFFSET 64
#define I1_OFFSET 72
#define I2_OFFSET 80
#define I3_OFFSET 88
#define I4_OFFSET 96
#define I5_OFFSET 104
#define I6_OFFSET 112
#define I7_OFFSET 120
 
/* Uspace Window Buffer constants. */
#define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE)
#define UWB_ALIGNMENT 1024
#define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT)
 
#ifdef __ASM__
 
/*
* Macro used by the nucleus and the primary context 0 during normal and other spills.
*/
.macro SPILL_NORMAL_HANDLER_KERNEL
stx %l0, [%sp + STACK_BIAS + L0_OFFSET]
stx %l1, [%sp + STACK_BIAS + L1_OFFSET]
stx %l2, [%sp + STACK_BIAS + L2_OFFSET]
stx %l3, [%sp + STACK_BIAS + L3_OFFSET]
stx %l4, [%sp + STACK_BIAS + L4_OFFSET]
stx %l5, [%sp + STACK_BIAS + L5_OFFSET]
stx %l6, [%sp + STACK_BIAS + L6_OFFSET]
stx %l7, [%sp + STACK_BIAS + L7_OFFSET]
stx %i0, [%sp + STACK_BIAS + I0_OFFSET]
stx %i1, [%sp + STACK_BIAS + I1_OFFSET]
stx %i2, [%sp + STACK_BIAS + I2_OFFSET]
stx %i3, [%sp + STACK_BIAS + I3_OFFSET]
stx %i4, [%sp + STACK_BIAS + I4_OFFSET]
stx %i5, [%sp + STACK_BIAS + I5_OFFSET]
stx %i6, [%sp + STACK_BIAS + I6_OFFSET]
stx %i7, [%sp + STACK_BIAS + I7_OFFSET]
saved
retry
.endm
 
/*
* Macro used by the userspace during normal spills.
*/
.macro SPILL_NORMAL_HANDLER_USERSPACE
wr %g0, ASI_AIUP, %asi
stxa %l0, [%sp + STACK_BIAS + L0_OFFSET] %asi
stxa %l1, [%sp + STACK_BIAS + L1_OFFSET] %asi
stxa %l2, [%sp + STACK_BIAS + L2_OFFSET] %asi
stxa %l3, [%sp + STACK_BIAS + L3_OFFSET] %asi
stxa %l4, [%sp + STACK_BIAS + L4_OFFSET] %asi
stxa %l5, [%sp + STACK_BIAS + L5_OFFSET] %asi
stxa %l6, [%sp + STACK_BIAS + L6_OFFSET] %asi
stxa %l7, [%sp + STACK_BIAS + L7_OFFSET] %asi
stxa %i0, [%sp + STACK_BIAS + I0_OFFSET] %asi
stxa %i1, [%sp + STACK_BIAS + I1_OFFSET] %asi
stxa %i2, [%sp + STACK_BIAS + I2_OFFSET] %asi
stxa %i3, [%sp + STACK_BIAS + I3_OFFSET] %asi
stxa %i4, [%sp + STACK_BIAS + I4_OFFSET] %asi
stxa %i5, [%sp + STACK_BIAS + I5_OFFSET] %asi
stxa %i6, [%sp + STACK_BIAS + I6_OFFSET] %asi
stxa %i7, [%sp + STACK_BIAS + I7_OFFSET] %asi
saved
retry
.endm
 
/*
* Macro used to spill userspace window to userspace window buffer.
* It can be either triggered from preemptible_handler doing SAVE
* at (TL=1) or from normal kernel code doing SAVE when OTHERWIN>0
* at (TL=0).
*/
.macro SPILL_TO_USPACE_WINDOW_BUFFER
stx %l0, [%g7 + L0_OFFSET]
stx %l1, [%g7 + L1_OFFSET]
stx %l2, [%g7 + L2_OFFSET]
stx %l3, [%g7 + L3_OFFSET]
stx %l4, [%g7 + L4_OFFSET]
stx %l5, [%g7 + L5_OFFSET]
stx %l6, [%g7 + L6_OFFSET]
stx %l7, [%g7 + L7_OFFSET]
stx %i0, [%g7 + I0_OFFSET]
stx %i1, [%g7 + I1_OFFSET]
stx %i2, [%g7 + I2_OFFSET]
stx %i3, [%g7 + I3_OFFSET]
stx %i4, [%g7 + I4_OFFSET]
stx %i5, [%g7 + I5_OFFSET]
stx %i6, [%g7 + I6_OFFSET]
stx %i7, [%g7 + I7_OFFSET]
add %g7, STACK_WINDOW_SAVE_AREA_SIZE, %g7
saved
retry
.endm
 
 
/*
* Macro used by the nucleus and the primary context 0 during normal fills.
*/
.macro FILL_NORMAL_HANDLER_KERNEL
ldx [%sp + STACK_BIAS + L0_OFFSET], %l0
ldx [%sp + STACK_BIAS + L1_OFFSET], %l1
ldx [%sp + STACK_BIAS + L2_OFFSET], %l2
ldx [%sp + STACK_BIAS + L3_OFFSET], %l3
ldx [%sp + STACK_BIAS + L4_OFFSET], %l4
ldx [%sp + STACK_BIAS + L5_OFFSET], %l5
ldx [%sp + STACK_BIAS + L6_OFFSET], %l6
ldx [%sp + STACK_BIAS + L7_OFFSET], %l7
ldx [%sp + STACK_BIAS + I0_OFFSET], %i0
ldx [%sp + STACK_BIAS + I1_OFFSET], %i1
ldx [%sp + STACK_BIAS + I2_OFFSET], %i2
ldx [%sp + STACK_BIAS + I3_OFFSET], %i3
ldx [%sp + STACK_BIAS + I4_OFFSET], %i4
ldx [%sp + STACK_BIAS + I5_OFFSET], %i5
ldx [%sp + STACK_BIAS + I6_OFFSET], %i6
ldx [%sp + STACK_BIAS + I7_OFFSET], %i7
restored
retry
.endm
 
/*
* Macro used by the userspace during normal fills.
*/
.macro FILL_NORMAL_HANDLER_USERSPACE
wr %g0, ASI_AIUP, %asi
ldxa [%sp + STACK_BIAS + L0_OFFSET] %asi, %l0
ldxa [%sp + STACK_BIAS + L1_OFFSET] %asi, %l1
ldxa [%sp + STACK_BIAS + L2_OFFSET] %asi, %l2
ldxa [%sp + STACK_BIAS + L3_OFFSET] %asi, %l3
ldxa [%sp + STACK_BIAS + L4_OFFSET] %asi, %l4
ldxa [%sp + STACK_BIAS + L5_OFFSET] %asi, %l5
ldxa [%sp + STACK_BIAS + L6_OFFSET] %asi, %l6
ldxa [%sp + STACK_BIAS + L7_OFFSET] %asi, %l7
ldxa [%sp + STACK_BIAS + I0_OFFSET] %asi, %i0
ldxa [%sp + STACK_BIAS + I1_OFFSET] %asi, %i1
ldxa [%sp + STACK_BIAS + I2_OFFSET] %asi, %i2
ldxa [%sp + STACK_BIAS + I3_OFFSET] %asi, %i3
ldxa [%sp + STACK_BIAS + I4_OFFSET] %asi, %i4
ldxa [%sp + STACK_BIAS + I5_OFFSET] %asi, %i5
ldxa [%sp + STACK_BIAS + I6_OFFSET] %asi, %i6
ldxa [%sp + STACK_BIAS + I7_OFFSET] %asi, %i7
restored
retry
.endm
 
.macro CLEAN_WINDOW_HANDLER
rdpr %cleanwin, %l0
add %l0, 1, %l0
wrpr %l0, 0, %cleanwin
mov %r0, %l0
mov %r0, %l1
mov %r0, %l2
mov %r0, %l3
mov %r0, %l4
mov %r0, %l5
mov %r0, %l6
mov %r0, %l7
mov %r0, %o0
mov %r0, %o1
mov %r0, %o2
mov %r0, %o3
mov %r0, %o4
mov %r0, %o5
mov %r0, %o6
mov %r0, %o7
retry
.endm
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/trap/syscall.h
0,0 → 1,45
/*
* 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 sparc64interrupt
* @{
*/
/**
* @file
* @brief
*/
 
#ifndef KERN_sparc64_SYSCALL_TRAP_H_
#define KERN_sparc64_SYSCALL_TRAP_H_
 
#define TT_TRAP_INSTRUCTION_0 0x100
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/trap/trap_table.h
0,0 → 1,112
/*
* Copyright (c) 2005 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 sparc64interrupt
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_TRAP_TABLE_H_
#define KERN_sparc64_TRAP_TABLE_H_
 
#include <arch/stack.h>
 
#define TRAP_TABLE_ENTRY_COUNT 1024
#define TRAP_TABLE_ENTRY_SIZE 32
#define TRAP_TABLE_SIZE (TRAP_TABLE_ENTRY_COUNT * TRAP_TABLE_ENTRY_SIZE)
 
#ifndef __ASM__
 
#include <arch/types.h>
 
struct trap_table_entry {
uint8_t octets[TRAP_TABLE_ENTRY_SIZE];
} __attribute__ ((packed));
 
typedef struct trap_table_entry trap_table_entry_t;
 
extern trap_table_entry_t trap_table[TRAP_TABLE_ENTRY_COUNT];
extern trap_table_entry_t trap_table_save[TRAP_TABLE_ENTRY_COUNT];
#endif /* !__ASM__ */
 
#ifdef __ASM__
.macro SAVE_GLOBALS
mov %g1, %l1
mov %g2, %l2
mov %g3, %l3
mov %g4, %l4
mov %g5, %l5
mov %g6, %l6
mov %g7, %l7
.endm
 
.macro RESTORE_GLOBALS
mov %l1, %g1
mov %l2, %g2
mov %l3, %g3
mov %l4, %g4
mov %l5, %g5
mov %l6, %g6
mov %l7, %g7
.endm
 
/*
* The following needs to be in sync with the definition of the istate
* structure. The one STACK_ITEM_SIZE is counted for space holding the 7th
* argument to syscall_handler (i.e. syscall number) and the other
* STACK_ITEM_SIZE is counted because of the required alignment.
*/
#define PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE \
(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE + \
(2 * STACK_ITEM_SIZE) + (12 * 8))
#define SAVED_TSTATE -(1 * 8)
#define SAVED_TPC -(2 * 8)
#define SAVED_TNPC -(3 * 8) /* <-- istate_t begins here */
#define SAVED_Y -(4 * 8)
#define SAVED_I0 -(5 * 8)
#define SAVED_I1 -(6 * 8)
#define SAVED_I2 -(7 * 8)
#define SAVED_I3 -(8 * 8)
#define SAVED_I4 -(9 * 8)
#define SAVED_I5 -(10 * 8)
#define SAVED_I6 -(11 * 8)
#define SAVED_I7 -(12 * 8)
 
.macro PREEMPTIBLE_HANDLER f
sethi %hi(\f), %g1
b preemptible_handler
or %g1, %lo(\f), %g1
.endm
 
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/trap/mmu.h
0,0 → 1,182
/*
* 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 sparc64interrupt
* @{
*/
/**
* @file
* @brief This file contains fast MMU trap handlers.
*/
 
#ifndef KERN_sparc64_MMU_TRAP_H_
#define KERN_sparc64_MMU_TRAP_H_
 
#include <arch/stack.h>
#include <arch/regdef.h>
#include <arch/mm/tlb.h>
#include <arch/mm/mmu.h>
#include <arch/mm/tte.h>
#include <arch/trap/regwin.h>
 
#ifdef CONFIG_TSB
#include <arch/mm/tsb.h>
#endif
 
#define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS 0x64
#define TT_FAST_DATA_ACCESS_MMU_MISS 0x68
#define TT_FAST_DATA_ACCESS_PROTECTION 0x6c
 
#define FAST_MMU_HANDLER_SIZE 128
 
#ifdef __ASM__
 
.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
/*
* First, try to refill TLB from TSB.
*/
#ifdef CONFIG_TSB
ldxa [%g0] ASI_IMMU, %g1 ! read TSB Tag Target Register
ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2 ! read TSB 8K Pointer
ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4 ! 16-byte atomic load into %g4 and %g5
cmp %g1, %g4 ! is this the entry we are looking for?
bne,pn %xcc, 0f
nop
stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG ! copy mapping from ITSB to ITLB
retry
#endif
 
0:
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
.endm
 
.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl
/*
* First, try to refill TLB from TSB.
*/
 
#ifdef CONFIG_TSB
ldxa [%g0] ASI_DMMU, %g1 ! read TSB Tag Target Register
srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2 ! is this a kernel miss?
brz,pn %g2, 0f
ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3 ! read TSB 8K Pointer
ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4 ! 16-byte atomic load into %g4 and %g5
cmp %g1, %g4 ! is this the entry we are looking for?
bne,pn %xcc, 0f
nop
stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG ! copy mapping from DTSB to DTLB
retry
#endif
 
/*
* Second, test if it is the portion of the kernel address space
* which is faulting. If that is the case, immediately create
* identity mapping for that page in DTLB. VPN 0 is excluded from
* this treatment.
*
* Note that branch-delay slots are used in order to save space.
*/
0:
mov VA_DMMU_TAG_ACCESS, %g1
ldxa [%g1] ASI_DMMU, %g1 ! read the faulting Context and VPN
set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
andcc %g1, %g2, %g3 ! get Context
bnz 0f ! Context is non-zero
andncc %g1, %g2, %g3 ! get page address into %g3
bz 0f ! page address is zero
 
sethi %hi(kernel_8k_tlb_data_template), %g2
ldx [%g2 + %lo(kernel_8k_tlb_data_template)], %g2
or %g3, %g2, %g2
stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG ! identity map the kernel page
retry
 
/*
* Third, catch and handle special cases when the trap is caused by
* the userspace register window spill or fill handler. In case
* one of these two traps caused this trap, we just lower the trap
* level and service the DTLB miss. In the end, we restart
* the offending SAVE or RESTORE.
*/
0:
.if (\tl > 0)
wrpr %g0, 1, %tl
.endif
 
/*
* Switch from the MM globals.
*/
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
/*
* Read the Tag Access register for the higher-level handler.
* This is necessary to survive nested DTLB misses.
*/
mov VA_DMMU_TAG_ACCESS, %g2
ldxa [%g2] ASI_DMMU, %g2
 
/*
* g2 will be passed as an argument to fast_data_access_mmu_miss().
*/
PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
.endm
 
.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl
/*
* The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
*/
 
.if (\tl > 0)
wrpr %g0, 1, %tl
.endif
 
/*
* Switch from the MM globals.
*/
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
/*
* Read the Tag Access register for the higher-level handler.
* This is necessary to survive nested DTLB misses.
*/
mov VA_DMMU_TAG_ACCESS, %g2
ldxa [%g2] ASI_DMMU, %g2
 
/*
* g2 will be passed as an argument to fast_data_access_mmu_miss().
*/
PREEMPTIBLE_HANDLER fast_data_access_protection
.endm
 
#endif /* __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/trap/exception.h
0,0 → 1,90
/*
* Copyright (c) 2005 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 sparc64interrupt
* @{
*/
/**
* @file
*/
 
#ifndef KERN_sparc64_EXCEPTION_H_
#define KERN_sparc64_EXCEPTION_H_
 
#define TT_INSTRUCTION_ACCESS_EXCEPTION 0x08
#define TT_INSTRUCTION_ACCESS_ERROR 0x0a
#define TT_ILLEGAL_INSTRUCTION 0x10
#define TT_PRIVILEGED_OPCODE 0x11
#define TT_UNIMPLEMENTED_LDD 0x12
#define TT_UNIMPLEMENTED_STD 0x13
#define TT_FP_DISABLED 0x20
#define TT_FP_EXCEPTION_IEEE_754 0x21
#define TT_FP_EXCEPTION_OTHER 0x22
#define TT_TAG_OVERFLOW 0x23
#define TT_DIVISION_BY_ZERO 0x28
#define TT_DATA_ACCESS_EXCEPTION 0x30
#define TT_DATA_ACCESS_ERROR 0x32
#define TT_MEM_ADDRESS_NOT_ALIGNED 0x34
#define TT_LDDF_MEM_ADDRESS_NOT_ALIGNED 0x35
#define TT_STDF_MEM_ADDRESS_NOT_ALIGNED 0x36
#define TT_PRIVILEGED_ACTION 0x37
#define TT_LDQF_MEM_ADDRESS_NOT_ALIGNED 0x38
#define TT_STQF_MEM_ADDRESS_NOT_ALIGNED 0x39
 
#ifndef __ASM__
 
#include <arch/interrupt.h>
 
extern void dump_istate(istate_t *istate);
 
extern void instruction_access_exception(int n, istate_t *istate);
extern void instruction_access_error(int n, istate_t *istate);
extern void illegal_instruction(int n, istate_t *istate);
extern void privileged_opcode(int n, istate_t *istate);
extern void unimplemented_LDD(int n, istate_t *istate);
extern void unimplemented_STD(int n, istate_t *istate);
extern void fp_disabled(int n, istate_t *istate);
extern void fp_exception_ieee_754(int n, istate_t *istate);
extern void fp_exception_other(int n, istate_t *istate);
extern void tag_overflow(int n, istate_t *istate);
extern void division_by_zero(int n, istate_t *istate);
extern void data_access_exception(int n, istate_t *istate);
extern void data_access_error(int n, istate_t *istate);
extern void mem_address_not_aligned(int n, istate_t *istate);
extern void LDDF_mem_address_not_aligned(int n, istate_t *istate);
extern void STDF_mem_address_not_aligned(int n, istate_t *istate);
extern void privileged_action(int n, istate_t *istate);
extern void LDQF_mem_address_not_aligned(int n, istate_t *istate);
extern void STQF_mem_address_not_aligned(int n, istate_t *istate);
 
#endif /* !__ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/trap/trap.h
0,0 → 1,44
/*
* Copyright (c) 2005 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 sparc64interrupt
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_TRAP_H_
#define KERN_sparc64_TRAP_H_
 
extern void trap_init(void);
 
#endif
 
/** @}
*/
 
/tags/0.4.0/kernel/arch/sparc64/include/mm/frame.h
0,0 → 1,85
/*
* Copyright (c) 2005 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
*/
 
#ifndef KERN_sparc64_FRAME_H_
#define KERN_sparc64_FRAME_H_
 
/*
* Page size supported by the MMU.
* For 8K there is the nasty illegal virtual aliasing problem.
* Therefore, the kernel uses 8K only internally on the TLB and TSB levels.
*/
#define MMU_FRAME_WIDTH 13 /* 8K */
#define MMU_FRAME_SIZE (1 << MMU_FRAME_WIDTH)
 
/*
* Page size exported to the generic memory management subsystems.
* This page size is not directly supported by the MMU, but we can emulate
* each 16K page with a pair of adjacent 8K pages.
*/
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
 
union frame_address {
uintptr_t address;
struct {
#if defined (US)
unsigned : 23;
uint64_t pfn : 28; /**< Physical Frame Number. */
#elif defined (US3)
unsigned : 21;
uint64_t pfn : 30; /**< Physical Frame Number. */
#endif
unsigned offset : 13; /**< Offset. */
} __attribute__ ((packed));
};
 
typedef union frame_address frame_address_t;
 
extern uintptr_t last_frame;
extern void frame_arch_init(void);
#define physmem_print()
 
#endif
#endif
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/tte.h
0,0 → 1,104
/*
* Copyright (c) 2005 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
*/
 
#ifndef KERN_sparc64_TTE_H_
#define KERN_sparc64_TTE_H_
 
#define TTE_G (1 << 0)
#define TTE_W (1 << 1)
#define TTE_P (1 << 2)
#define TTE_E (1 << 3)
#define TTE_CV (1 << 4)
#define TTE_CP (1 << 5)
#define TTE_L (1 << 6)
 
#define TTE_V_SHIFT 63
#define TTE_SIZE_SHIFT 61
 
#ifndef __ASM__
 
#include <arch/types.h>
 
/* TTE tag's VA_tag field contains bits <63:VA_TAG_PAGE_SHIFT> of the VA */
#define VA_TAG_PAGE_SHIFT 22
 
/** Translation Table Entry - Tag. */
union tte_tag {
uint64_t value;
struct {
unsigned g : 1; /**< Global. */
unsigned : 2; /**< Reserved. */
unsigned context : 13; /**< Context identifier. */
unsigned : 6; /**< Reserved. */
uint64_t va_tag : 42; /**< Virtual Address Tag, bits 63:22. */
} __attribute__ ((packed));
};
 
typedef union tte_tag tte_tag_t;
 
/** Translation Table Entry - Data. */
union tte_data {
uint64_t value;
struct {
unsigned v : 1; /**< Valid. */
unsigned size : 2; /**< Page size of this entry. */
unsigned nfo : 1; /**< No-Fault-Only. */
unsigned ie : 1; /**< Invert Endianness. */
unsigned soft2 : 9; /**< Software defined field. */
#if defined (US)
unsigned diag : 9; /**< Diagnostic data. */
unsigned pfn : 28; /**< Physical Address bits, bits 40:13. */
#elif defined (US3)
unsigned : 7; /**< Reserved. */
unsigned pfn : 30; /**< Physical Address bits, bits 42:13 */
#endif
unsigned soft : 6; /**< Software defined field. */
unsigned l : 1; /**< Lock. */
unsigned cp : 1; /**< Cacheable in physically indexed cache. */
unsigned cv : 1; /**< Cacheable in virtually indexed cache. */
unsigned e : 1; /**< Side-effect. */
unsigned p : 1; /**< Privileged. */
unsigned w : 1; /**< Writable. */
unsigned g : 1; /**< Global. */
} __attribute__ ((packed));
};
 
typedef union tte_data tte_data_t;
 
#endif /* !def __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/cache_spec.h
0,0 → 1,58
/*
* Copyright (c) 2008 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
*/
 
#ifndef KERN_sparc64_CACHE_SPEC_H_
#define KERN_sparc64_CACHE_SPEC_H_
 
/*
* The following macros are valid for the following processors:
*
* UltraSPARC, UltraSPARC II, UltraSPARC IIi, UltraSPARC III,
* UltraSPARC III+, UltraSPARC IV, UltraSPARC IV+
*
* Should we support other UltraSPARC processors, we need to make sure that
* the macros are defined correctly for them.
*/
#if defined (US)
#define DCACHE_SIZE (16 * 1024)
#elif defined (US3)
#define DCACHE_SIZE (64 * 1024)
#endif
#define DCACHE_LINE_SIZE 32
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/mmu.h
0,0 → 1,123
/*
* Copyright (c) 2005 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
*/
 
#ifndef KERN_sparc64_MMU_H_
#define KERN_sparc64_MMU_H_
 
#if defined(US)
/* LSU Control Register ASI. */
#define ASI_LSU_CONTROL_REG 0x45 /**< Load/Store Unit Control Register. */
#endif
 
/* I-MMU ASIs. */
#define ASI_IMMU 0x50
#define ASI_IMMU_TSB_8KB_PTR_REG 0x51
#define ASI_IMMU_TSB_64KB_PTR_REG 0x52
#define ASI_ITLB_DATA_IN_REG 0x54
#define ASI_ITLB_DATA_ACCESS_REG 0x55
#define ASI_ITLB_TAG_READ_REG 0x56
#define ASI_IMMU_DEMAP 0x57
 
/* Virtual Addresses within ASI_IMMU. */
#define VA_IMMU_TSB_TAG_TARGET 0x0 /**< IMMU TSB tag target register. */
#define VA_IMMU_SFSR 0x18 /**< IMMU sync fault status register. */
#define VA_IMMU_TSB_BASE 0x28 /**< IMMU TSB base register. */
#define VA_IMMU_TAG_ACCESS 0x30 /**< IMMU TLB tag access register. */
#if defined (US3)
#define VA_IMMU_PRIMARY_EXTENSION 0x48 /**< IMMU TSB primary extension register */
#define VA_IMMU_NUCLEUS_EXTENSION 0x58 /**< IMMU TSB nucleus extension register */
#endif
 
 
/* D-MMU ASIs. */
#define ASI_DMMU 0x58
#define ASI_DMMU_TSB_8KB_PTR_REG 0x59
#define ASI_DMMU_TSB_64KB_PTR_REG 0x5a
#define ASI_DMMU_TSB_DIRECT_PTR_REG 0x5b
#define ASI_DTLB_DATA_IN_REG 0x5c
#define ASI_DTLB_DATA_ACCESS_REG 0x5d
#define ASI_DTLB_TAG_READ_REG 0x5e
#define ASI_DMMU_DEMAP 0x5f
 
/* Virtual Addresses within ASI_DMMU. */
#define VA_DMMU_TSB_TAG_TARGET 0x0 /**< DMMU TSB tag target register. */
#define VA_PRIMARY_CONTEXT_REG 0x8 /**< DMMU primary context register. */
#define VA_SECONDARY_CONTEXT_REG 0x10 /**< DMMU secondary context register. */
#define VA_DMMU_SFSR 0x18 /**< DMMU sync fault status register. */
#define VA_DMMU_SFAR 0x20 /**< DMMU sync fault address register. */
#define VA_DMMU_TSB_BASE 0x28 /**< DMMU TSB base register. */
#define VA_DMMU_TAG_ACCESS 0x30 /**< DMMU TLB tag access register. */
#define VA_DMMU_VA_WATCHPOINT_REG 0x38 /**< DMMU VA data watchpoint register. */
#define VA_DMMU_PA_WATCHPOINT_REG 0x40 /**< DMMU PA data watchpoint register. */
#if defined (US3)
#define VA_DMMU_PRIMARY_EXTENSION 0x48 /**< DMMU TSB primary extension register */
#define VA_DMMU_SECONDARY_EXTENSION 0x50 /**< DMMU TSB secondary extension register */
#define VA_DMMU_NUCLEUS_EXTENSION 0x58 /**< DMMU TSB nucleus extension register */
#endif
 
#ifndef __ASM__
 
#include <arch/asm.h>
#include <arch/barrier.h>
#include <arch/types.h>
 
#if defined(US)
/** LSU Control Register. */
typedef union {
uint64_t value;
struct {
unsigned : 23;
unsigned pm : 8;
unsigned vm : 8;
unsigned pr : 1;
unsigned pw : 1;
unsigned vr : 1;
unsigned vw : 1;
unsigned : 1;
unsigned fm : 16;
unsigned dm : 1; /**< D-MMU enable. */
unsigned im : 1; /**< I-MMU enable. */
unsigned dc : 1; /**< D-Cache enable. */
unsigned ic : 1; /**< I-Cache enable. */
} __attribute__ ((packed));
} lsu_cr_reg_t;
#endif /* US */
 
#endif /* !def __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/tlb.h
0,0 → 1,692
/*
* Copyright (c) 2005 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
*/
 
#ifndef KERN_sparc64_TLB_H_
#define KERN_sparc64_TLB_H_
 
#if defined (US)
#define ITLB_ENTRY_COUNT 64
#define DTLB_ENTRY_COUNT 64
#define DTLB_MAX_LOCKED_ENTRIES DTLB_ENTRY_COUNT
#endif
 
/** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */
#if defined (US3)
#define DTLB_MAX_LOCKED_ENTRIES 16
#endif
 
#define MEM_CONTEXT_KERNEL 0
#define MEM_CONTEXT_TEMP 1
 
/** Page sizes. */
#define PAGESIZE_8K 0
#define PAGESIZE_64K 1
#define PAGESIZE_512K 2
#define PAGESIZE_4M 3
 
/** Bit width of the TLB-locked portion of kernel address space. */
#define KERNEL_PAGE_WIDTH 22 /* 4M */
 
/* TLB Demap Operation types. */
#define TLB_DEMAP_PAGE 0
#define TLB_DEMAP_CONTEXT 1
#if defined (US3)
#define TLB_DEMAP_ALL 2
#endif
 
#define TLB_DEMAP_TYPE_SHIFT 6
 
/* TLB Demap Operation Context register encodings. */
#define TLB_DEMAP_PRIMARY 0
#define TLB_DEMAP_SECONDARY 1
#define TLB_DEMAP_NUCLEUS 2
 
/* There are more TLBs in one MMU in US3, their codes are defined here. */
#if defined (US3)
/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */
#define TLB_DSMALL 0
#define TLB_DBIG_0 2
#define TLB_DBIG_1 3
/* I-MMU: one small (16-entry) TLB and one big TLB */
#define TLB_ISMALL 0
#define TLB_IBIG 2
#endif
 
#define TLB_DEMAP_CONTEXT_SHIFT 4
 
/* TLB Tag Access shifts */
#define TLB_TAG_ACCESS_CONTEXT_SHIFT 0
#define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
#define TLB_TAG_ACCESS_VPN_SHIFT 13
 
#ifndef __ASM__
 
#include <arch/mm/tte.h>
#include <arch/mm/mmu.h>
#include <arch/mm/page.h>
#include <arch/asm.h>
#include <arch/barrier.h>
#include <arch/types.h>
#include <arch/register.h>
#include <arch/cpu.h>
 
union tlb_context_reg {
uint64_t v;
struct {
unsigned long : 51;
unsigned context : 13; /**< Context/ASID. */
} __attribute__ ((packed));
};
typedef union tlb_context_reg tlb_context_reg_t;
 
/** I-/D-TLB Data In/Access Register type. */
typedef tte_data_t tlb_data_t;
 
/** I-/D-TLB Data Access Address in Alternate Space. */
 
#if defined (US)
 
union tlb_data_access_addr {
uint64_t value;
struct {
uint64_t : 55;
unsigned tlb_entry : 6;
unsigned : 3;
} __attribute__ ((packed));
};
typedef union tlb_data_access_addr dtlb_data_access_addr_t;
typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
typedef union tlb_data_access_addr itlb_data_access_addr_t;
typedef union tlb_data_access_addr itlb_tag_read_addr_t;
 
#elif defined (US3)
 
/*
* In US3, I-MMU and D-MMU have different formats of the data
* access register virtual address. In the corresponding
* structures the member variable for the entry number is
* called "local_tlb_entry" - it contrasts with the "tlb_entry"
* for the US data access register VA structure. The rationale
* behind this is to prevent careless mistakes in the code
* caused by setting only the entry number and not the TLB
* number in the US3 code (when taking the code from US).
*/
 
union dtlb_data_access_addr {
uint64_t value;
struct {
uint64_t : 45;
unsigned : 1;
unsigned tlb_number : 2;
unsigned : 4;
unsigned local_tlb_entry : 9;
unsigned : 3;
} __attribute__ ((packed));
};
typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
 
union itlb_data_access_addr {
uint64_t value;
struct {
uint64_t : 45;
unsigned : 1;
unsigned tlb_number : 2;
unsigned : 6;
unsigned local_tlb_entry : 7;
unsigned : 3;
} __attribute__ ((packed));
};
typedef union itlb_data_access_addr itlb_data_access_addr_t;
typedef union itlb_data_access_addr itlb_tag_read_addr_t;
 
#endif
 
/** I-/D-TLB Tag Read Register. */
union tlb_tag_read_reg {
uint64_t value;
struct {
uint64_t vpn : 51; /**< Virtual Address bits 63:13. */
unsigned context : 13; /**< Context identifier. */
} __attribute__ ((packed));
};
typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
 
 
/** TLB Demap Operation Address. */
union tlb_demap_addr {
uint64_t value;
struct {
uint64_t vpn: 51; /**< Virtual Address bits 63:13. */
#if defined (US)
unsigned : 6; /**< Ignored. */
unsigned type : 1; /**< The type of demap operation. */
#elif defined (US3)
unsigned : 5; /**< Ignored. */
unsigned type: 2; /**< The type of demap operation. */
#endif
unsigned context : 2; /**< Context register selection. */
unsigned : 4; /**< Zero. */
} __attribute__ ((packed));
};
typedef union tlb_demap_addr tlb_demap_addr_t;
 
/** TLB Synchronous Fault Status Register. */
union tlb_sfsr_reg {
uint64_t value;
struct {
#if defined (US)
unsigned long : 40; /**< Implementation dependent. */
unsigned asi : 8; /**< ASI. */
unsigned : 2;
unsigned ft : 7; /**< Fault type. */
#elif defined (US3)
unsigned long : 39; /**< Implementation dependent. */
unsigned nf : 1; /**< Non-faulting load. */
unsigned asi : 8; /**< ASI. */
unsigned tm : 1; /**< I-TLB miss. */
unsigned : 3; /**< Reserved. */
unsigned ft : 5; /**< Fault type. */
#endif
unsigned e : 1; /**< Side-effect bit. */
unsigned ct : 2; /**< Context Register selection. */
unsigned pr : 1; /**< Privilege bit. */
unsigned w : 1; /**< Write bit. */
unsigned ow : 1; /**< Overwrite bit. */
unsigned fv : 1; /**< Fault Valid bit. */
} __attribute__ ((packed));
};
typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
 
#if defined (US3)
 
/*
* Functions for determining the number of entries in TLBs. They either return
* a constant value or a value based on the CPU autodetection.
*/
 
/**
* Determine the number of entries in the DMMU's small TLB.
*/
static inline uint16_t tlb_dsmall_size(void)
{
return 16;
}
 
/**
* Determine the number of entries in each DMMU's big TLB.
*/
static inline uint16_t tlb_dbig_size(void)
{
return 512;
}
 
/**
* Determine the number of entries in the IMMU's small TLB.
*/
static inline uint16_t tlb_ismall_size(void)
{
return 16;
}
 
/**
* Determine the number of entries in the IMMU's big TLB.
*/
static inline uint16_t tlb_ibig_size(void)
{
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
return 512;
else
return 128;
}
 
#endif
 
/** Read MMU Primary Context Register.
*
* @return Current value of Primary Context Register.
*/
static inline uint64_t mmu_primary_context_read(void)
{
return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
}
 
/** Write MMU Primary Context Register.
*
* @param v New value of Primary Context Register.
*/
static inline void mmu_primary_context_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
flush_pipeline();
}
 
/** Read MMU Secondary Context Register.
*
* @return Current value of Secondary Context Register.
*/
static inline uint64_t mmu_secondary_context_read(void)
{
return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
}
 
/** Write MMU Primary Context Register.
*
* @param v New value of Primary Context Register.
*/
static inline void mmu_secondary_context_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
flush_pipeline();
}
 
#if defined (US)
 
/** Read IMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Data Access
* Register.
*/
static inline uint64_t itlb_data_access_read(index_t entry)
{
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write IMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void itlb_data_access_write(index_t entry, uint64_t value)
{
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
flush_pipeline();
}
 
/** Read DMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Data Access
* Register.
*/
static inline uint64_t dtlb_data_access_read(index_t entry)
{
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write DMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void dtlb_data_access_write(index_t entry, uint64_t value)
{
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
membar();
}
 
/** Read IMMU TLB Tag Read Register.
*
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Tag Read Register.
*/
static inline uint64_t itlb_tag_read_read(index_t entry)
{
itlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_entry = entry;
return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
}
 
/** Read DMMU TLB Tag Read Register.
*
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Tag Read Register.
*/
static inline uint64_t dtlb_tag_read_read(index_t entry)
{
dtlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_entry = entry;
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
}
 
#elif defined (US3)
 
 
/** Read IMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Data Access
* Register.
*/
static inline uint64_t itlb_data_access_read(int tlb, index_t entry)
{
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write IMMU TLB Data Access Register.
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void itlb_data_access_write(int tlb, index_t entry,
uint64_t value)
{
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
flush_pipeline();
}
 
/** Read DMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Data Access
* Register.
*/
static inline uint64_t dtlb_data_access_read(int tlb, index_t entry)
{
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write DMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void dtlb_data_access_write(int tlb, index_t entry,
uint64_t value)
{
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
membar();
}
 
/** Read IMMU TLB Tag Read Register.
*
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Tag Read Register.
*/
static inline uint64_t itlb_tag_read_read(int tlb, index_t entry)
{
itlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_number = tlb;
tag.local_tlb_entry = entry;
return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
}
 
/** Read DMMU TLB Tag Read Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Tag Read Register.
*/
static inline uint64_t dtlb_tag_read_read(int tlb, index_t entry)
{
dtlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_number = tlb;
tag.local_tlb_entry = entry;
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
}
 
#endif
 
 
/** Write IMMU TLB Tag Access Register.
*
* @param v Value to be written.
*/
static inline void itlb_tag_access_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
flush_pipeline();
}
 
/** Read IMMU TLB Tag Access Register.
*
* @return Current value of IMMU TLB Tag Access Register.
*/
static inline uint64_t itlb_tag_access_read(void)
{
return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
}
 
/** Write DMMU TLB Tag Access Register.
*
* @param v Value to be written.
*/
static inline void dtlb_tag_access_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
membar();
}
 
/** Read DMMU TLB Tag Access Register.
*
* @return Current value of DMMU TLB Tag Access Register.
*/
static inline uint64_t dtlb_tag_access_read(void)
{
return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
}
 
 
/** Write IMMU TLB Data in Register.
*
* @param v Value to be written.
*/
static inline void itlb_data_in_write(uint64_t v)
{
asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
flush_pipeline();
}
 
/** Write DMMU TLB Data in Register.
*
* @param v Value to be written.
*/
static inline void dtlb_data_in_write(uint64_t v)
{
asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
membar();
}
 
/** Read ITLB Synchronous Fault Status Register.
*
* @return Current content of I-SFSR register.
*/
static inline uint64_t itlb_sfsr_read(void)
{
return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
}
 
/** Write ITLB Synchronous Fault Status Register.
*
* @param v New value of I-SFSR register.
*/
static inline void itlb_sfsr_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
flush_pipeline();
}
 
/** Read DTLB Synchronous Fault Status Register.
*
* @return Current content of D-SFSR register.
*/
static inline uint64_t dtlb_sfsr_read(void)
{
return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
}
 
/** Write DTLB Synchronous Fault Status Register.
*
* @param v New value of D-SFSR register.
*/
static inline void dtlb_sfsr_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
membar();
}
 
/** Read DTLB Synchronous Fault Address Register.
*
* @return Current content of D-SFAR register.
*/
static inline uint64_t dtlb_sfar_read(void)
{
return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
}
 
/** Perform IMMU TLB Demap Operation.
*
* @param type Selects between context and page demap (and entire MMU
* demap on US3).
* @param context_encoding Specifies which Context register has Context ID for
* demap.
* @param page Address which is on the page to be demapped.
*/
static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
{
tlb_demap_addr_t da;
page_address_t pg;
da.value = 0;
pg.address = page;
da.type = type;
da.context = context_encoding;
da.vpn = pg.vpn;
/* da.value is the address within the ASI */
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
 
flush_pipeline();
}
 
/** Perform DMMU TLB Demap Operation.
*
* @param type Selects between context and page demap (and entire MMU
* demap on US3).
* @param context_encoding Specifies which Context register has Context ID for
* demap.
* @param page Address which is on the page to be demapped.
*/
static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
{
tlb_demap_addr_t da;
page_address_t pg;
da.value = 0;
pg.address = page;
da.type = type;
da.context = context_encoding;
da.vpn = pg.vpn;
/* da.value is the address within the ASI */
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
 
membar();
}
 
extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
 
extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
 
extern void dump_sfsr_and_sfar(void);
 
#endif /* !def __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/cache.h
0,0 → 1,44
/*
* 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
*/
 
#ifndef KERN_sparc64_CACHE_H_
#define KERN_sparc64_CACHE_H_
 
#include <mm/page.h>
#include <mm/frame.h>
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/tsb.h
0,0 → 1,172
/*
* 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
*/
 
#ifndef KERN_sparc64_TSB_H_
#define KERN_sparc64_TSB_H_
 
/*
* ITSB abd DTSB will claim 64K of memory, which
* is a nice number considered that it is one of
* the page sizes supported by hardware, which,
* again, is nice because TSBs need to be locked
* in TLBs - only one TLB entry will do.
*/
#define TSB_SIZE 2 /* when changing this, change
* as.c as well */
#define ITSB_ENTRY_COUNT (512 * (1 << TSB_SIZE))
#define DTSB_ENTRY_COUNT (512 * (1 << TSB_SIZE))
 
#define TSB_TAG_TARGET_CONTEXT_SHIFT 48
 
#ifndef __ASM__
 
#include <arch/mm/tte.h>
#include <arch/mm/mmu.h>
#include <arch/types.h>
 
/** TSB Base register. */
typedef union tsb_base_reg {
uint64_t value;
struct {
uint64_t base : 51; /**< TSB base address, bits 63:13. */
unsigned split : 1; /**< Split vs. common TSB for 8K and 64K
* pages. HelenOS uses only 8K pages
* for user mappings, so we always set
* this to 0.
*/
unsigned : 9;
unsigned size : 3; /**< TSB size. Number of entries is
* 512 * 2^size. */
} __attribute__ ((packed));
} tsb_base_reg_t;
 
/** Read ITSB Base register.
*
* @return Content of the ITSB Base register.
*/
static inline uint64_t itsb_base_read(void)
{
return asi_u64_read(ASI_IMMU, VA_IMMU_TSB_BASE);
}
 
/** Read DTSB Base register.
*
* @return Content of the DTSB Base register.
*/
static inline uint64_t dtsb_base_read(void)
{
return asi_u64_read(ASI_DMMU, VA_DMMU_TSB_BASE);
}
 
/** Write ITSB Base register.
*
* @param v New content of the ITSB Base register.
*/
static inline void itsb_base_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_TSB_BASE, v);
}
 
/** Write DTSB Base register.
*
* @param v New content of the DTSB Base register.
*/
static inline void dtsb_base_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_TSB_BASE, v);
}
 
#if defined (US3)
 
/** Write DTSB Primary Extension register.
*
* @param v New content of the DTSB Primary Extension register.
*/
static inline void dtsb_primary_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_PRIMARY_EXTENSION, v);
}
 
/** Write DTSB Secondary Extension register.
*
* @param v New content of the DTSB Secondary Extension register.
*/
static inline void dtsb_secondary_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_SECONDARY_EXTENSION, v);
}
 
/** Write DTSB Nucleus Extension register.
*
* @param v New content of the DTSB Nucleus Extension register.
*/
static inline void dtsb_nucleus_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_NUCLEUS_EXTENSION, v);
}
 
/** Write ITSB Primary Extension register.
*
* @param v New content of the ITSB Primary Extension register.
*/
static inline void itsb_primary_extension_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_PRIMARY_EXTENSION, v);
}
 
/** Write ITSB Nucleus Extension register.
*
* @param v New content of the ITSB Nucleus Extension register.
*/
static inline void itsb_nucleus_extension_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_NUCLEUS_EXTENSION, v);
}
 
#endif
 
/* Forward declarations. */
struct as;
struct pte;
 
extern void tsb_invalidate(struct as *as, uintptr_t page, count_t pages);
extern void itsb_pte_copy(struct pte *t, index_t index);
extern void dtsb_pte_copy(struct pte *t, index_t index, bool ro);
 
#endif /* !def __ASM__ */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/page.h
0,0 → 1,84
/*
* Copyright (c) 2005 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
*/
 
#ifndef KERN_sparc64_PAGE_H_
#define KERN_sparc64_PAGE_H_
 
#include <arch/mm/frame.h>
 
/*
* On the TLB and TSB level, we still use 8K pages, which are supported by the
* MMU.
*/
#define MMU_PAGE_WIDTH MMU_FRAME_WIDTH
#define MMU_PAGE_SIZE MMU_FRAME_SIZE
 
/*
* On the page table level, we use 16K pages. 16K pages are not supported by
* the MMU but we emulate them with pairs of 8K pages.
*/
#define PAGE_WIDTH FRAME_WIDTH
#define PAGE_SIZE FRAME_SIZE
 
#define MMU_PAGES_PER_PAGE (1 << (PAGE_WIDTH - MMU_PAGE_WIDTH))
 
#ifdef KERNEL
 
#ifndef __ASM__
 
#include <arch/interrupt.h>
 
extern uintptr_t physmem_base;
 
#define KA2PA(x) (((uintptr_t) (x)) + physmem_base)
#define PA2KA(x) (((uintptr_t) (x)) - physmem_base)
 
typedef union {
uintptr_t address;
struct {
uint64_t vpn : 51; /**< Virtual Page Number. */
unsigned offset : 13; /**< Offset. */
} __attribute__ ((packed));
} page_address_t;
 
extern void page_arch_init(void);
 
#endif /* !def __ASM__ */
 
#endif /* KERNEL */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/as.h
0,0 → 1,96
/*
* Copyright (c) 2005 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
*/
 
#ifndef KERN_sparc64_AS_H_
#define KERN_sparc64_AS_H_
 
#include <arch/mm/tte.h>
 
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 1
 
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff
#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000
#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffff
 
#define USTACK_ADDRESS_ARCH (0xffffffffffffffffULL - (PAGE_SIZE - 1))
 
#ifdef CONFIG_TSB
 
/** TSB Tag Target register. */
typedef union tsb_tag_target {
uint64_t value;
struct {
unsigned invalid : 1; /**< Invalidated by software. */
unsigned : 2;
unsigned context : 13; /**< Software ASID. */
unsigned : 6;
uint64_t va_tag : 42; /**< Virtual address bits <63:22>. */
} __attribute__ ((packed));
} tsb_tag_target_t;
 
/** TSB entry. */
typedef struct tsb_entry {
tsb_tag_target_t tag;
tte_data_t data;
} __attribute__ ((packed)) tsb_entry_t;
 
typedef struct {
tsb_entry_t *itsb;
tsb_entry_t *dtsb;
} as_arch_t;
 
#else
 
typedef struct {
} as_arch_t;
 
#endif /* CONFIG_TSB */
 
#include <genarch/mm/as_ht.h>
 
#ifdef CONFIG_TSB
#include <arch/mm/tsb.h>
#define as_invalidate_translation_cache(as, page, cnt) \
tsb_invalidate((as), (page), (cnt))
#else
#define as_invalidate_translation_cache(as, page, cnt)
#endif
 
extern void as_arch_init(void);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/mm/asid.h
0,0 → 1,50
/*
* Copyright (c) 2005 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
*/
 
#ifndef KERN_sparc64_ASID_H_
#define KERN_sparc64_ASID_H_
 
#include <arch/types.h>
 
/*
* On SPARC, Context means the same thing as ASID trough out the kernel.
*/
typedef uint16_t asid_t;
 
#define ASID_MAX_ARCH 8191 /* 2^13 - 1 */
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/register.h
0,0 → 1,123
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_REGISTER_H_
#define KERN_sparc64_REGISTER_H_
 
#include <arch/regdef.h>
#include <arch/types.h>
 
/** Version Register. */
union ver_reg {
uint64_t value;
struct {
uint16_t manuf; /**< Manufacturer code. */
uint16_t impl; /**< Implementation code. */
uint8_t mask; /**< Mask set revision. */
unsigned : 8;
uint8_t maxtl;
unsigned : 3;
unsigned maxwin : 5;
} __attribute__ ((packed));
};
typedef union ver_reg ver_reg_t;
 
/** Processor State Register. */
union pstate_reg {
uint64_t value;
struct {
uint64_t : 52;
unsigned ig : 1; /**< Interrupt Globals. */
unsigned mg : 1; /**< MMU Globals. */
unsigned cle : 1; /**< Current Little Endian. */
unsigned tle : 1; /**< Trap Little Endian. */
unsigned mm : 2; /**< Memory Model. */
unsigned red : 1; /**< RED state. */
unsigned pef : 1; /**< Enable floating-point. */
unsigned am : 1; /**< 32-bit Address Mask. */
unsigned priv : 1; /**< Privileged Mode. */
unsigned ie : 1; /**< Interrupt Enable. */
unsigned ag : 1; /**< Alternate Globals*/
} __attribute__ ((packed));
};
typedef union pstate_reg pstate_reg_t;
 
/** TICK Register. */
union tick_reg {
uint64_t value;
struct {
unsigned npt : 1; /**< Non-privileged Trap enable. */
uint64_t counter : 63; /**< Elapsed CPU clck cycle counter. */
} __attribute__ ((packed));
};
typedef union tick_reg tick_reg_t;
 
/** TICK_compare Register. */
union tick_compare_reg {
uint64_t value;
struct {
unsigned int_dis : 1; /**< TICK_INT interrupt disabled flag. */
uint64_t tick_cmpr : 63; /**< Compare value for TICK interrupts. */
} __attribute__ ((packed));
};
typedef union tick_compare_reg tick_compare_reg_t;
 
/** SOFTINT Register. */
union softint_reg {
uint64_t value;
struct {
uint64_t : 47;
unsigned stick_int : 1;
unsigned int_level : 15;
unsigned tick_int : 1;
} __attribute__ ((packed));
};
typedef union softint_reg softint_reg_t;
 
/** Floating-point Registers State Register. */
union fprs_reg {
uint64_t value;
struct {
uint64_t : 61;
unsigned fef : 1;
unsigned du : 1;
unsigned dl : 1;
} __attribute__ ((packed));
};
typedef union fprs_reg fprs_reg_t;
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/cpu.h
0,0 → 1,99
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CPU_H_
#define KERN_sparc64_CPU_H_
 
#define MANUF_FUJITSU 0x04
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */
#define MANUF_SUN 0x3e
 
#define IMPL_ULTRASPARCI 0x10
#define IMPL_ULTRASPARCII 0x11
#define IMPL_ULTRASPARCII_I 0x12
#define IMPL_ULTRASPARCII_E 0x13
#define IMPL_ULTRASPARCIII 0x14
#define IMPL_ULTRASPARCIII_PLUS 0x15
#define IMPL_ULTRASPARCIII_I 0x16
#define IMPL_ULTRASPARCIV 0x18
#define IMPL_ULTRASPARCIV_PLUS 0x19
 
#define IMPL_SPARC64V 0x5
 
#ifndef __ASM__
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/register.h>
#include <arch/regdef.h>
#include <arch/asm.h>
 
#ifdef CONFIG_SMP
#include <arch/mm/cache.h>
#endif
 
typedef struct {
uint32_t mid; /**< Processor ID as read from
UPA_CONFIG/FIREPLANE_CONFIG. */
ver_reg_t ver;
uint32_t clock_frequency; /**< Processor frequency in Hz. */
uint64_t next_tick_cmpr; /**< Next clock interrupt should be
generated when the TICK register
matches this value. */
} cpu_arch_t;
 
 
/**
* Reads the module ID (agent ID/CPUID) of the current CPU.
*/
static inline uint32_t read_mid(void)
{
uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0);
icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT;
#if defined (US)
return icbus_config & 0x1f;
#elif defined (US3)
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I)
return icbus_config & 0x1f;
else
return icbus_config & 0x3ff;
#endif
}
 
#endif
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/cpu_family.h
0,0 → 1,82
/*
* Copyright (c) 2008 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CPU_FAMILY_H_
#define KERN_sparc64_CPU_FAMILY_H_
 
#include <arch.h>
#include <cpu.h>
#include <arch/register.h>
#include <arch/asm.h>
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US family
*/
static inline bool is_us(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCI) || (impl == IMPL_ULTRASPARCII) ||
(impl == IMPL_ULTRASPARCII_I) || (impl == IMPL_ULTRASPARCII_E);
}
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US-III subfamily
*/
static inline bool is_us_iii(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCIII) ||
(impl == IMPL_ULTRASPARCIII_PLUS) ||
(impl == IMPL_ULTRASPARCIII_I);
}
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US-IV subfamily
*/
static inline bool is_us_iv(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCIV) || (impl == IMPL_ULTRASPARCIV_PLUS);
}
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/atomic.h
0,0 → 1,141
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_ATOMIC_H_
#define KERN_sparc64_ATOMIC_H_
 
#include <arch/barrier.h>
#include <arch/types.h>
#include <preemption.h>
 
/** Atomic add operation.
*
* Use atomic compare and swap operation to atomically add signed value.
*
* @param val Atomic variable.
* @param i Signed value to be added.
*
* @return Value of the atomic variable as it existed before addition.
*/
static inline long atomic_add(atomic_t *val, int i)
{
uint64_t a, b;
 
do {
volatile uintptr_t x = (uint64_t) &val->count;
 
a = *((uint64_t *) x);
b = a + i;
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *)x)),
"+r" (b) : "r" (a));
} while (a != b);
 
return a;
}
 
static inline long atomic_preinc(atomic_t *val)
{
return atomic_add(val, 1) + 1;
}
 
static inline long atomic_postinc(atomic_t *val)
{
return atomic_add(val, 1);
}
 
static inline long atomic_predec(atomic_t *val)
{
return atomic_add(val, -1) - 1;
}
 
static inline long atomic_postdec(atomic_t *val)
{
return atomic_add(val, -1);
}
 
static inline void atomic_inc(atomic_t *val)
{
(void) atomic_add(val, 1);
}
 
static inline void atomic_dec(atomic_t *val)
{
(void) atomic_add(val, -1);
}
 
static inline long test_and_set(atomic_t *val)
{
uint64_t v = 1;
volatile uintptr_t x = (uint64_t) &val->count;
 
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *) x)),
"+r" (v) : "r" (0));
 
return v;
}
 
static inline void atomic_lock_arch(atomic_t *val)
{
uint64_t tmp1 = 1;
uint64_t tmp2 = 0;
 
volatile uintptr_t x = (uint64_t) &val->count;
 
preemption_disable();
 
asm volatile (
"0:\n"
"casx %0, %3, %1\n"
"brz %1, 2f\n"
"nop\n"
"1:\n"
"ldx %0, %2\n"
"brz %2, 0b\n"
"nop\n"
"ba 1b\n"
"nop\n"
"2:\n"
: "+m" (*((uint64_t *) x)), "+r" (tmp1), "+r" (tmp2) : "r" (0)
);
/*
* Prevent critical section code from bleeding out this way up.
*/
CS_ENTER_BARRIER();
}
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/memstr.h
0,0 → 1,48
/*
* Copyright (c) 2005 Sergey Bondari
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_MEMSTR_H_
#define KERN_sparc64_MEMSTR_H_
 
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt))
 
extern void memsetw(void *dst, size_t cnt, uint16_t x);
extern void memsetb(void *dst, size_t cnt, uint8_t x);
 
extern int memcmp(const void *a, const void *b, size_t cnt);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/context_offset.h
0,0 → 1,107
/*
* Copyright (c) 2005 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.
*/
 
#ifndef KERN_sparc64_CONTEXT_OFFSET_H_
#define KERN_sparc64_CONTEXT_OFFSET_H_
 
#define OFFSET_SP 0x0
#define OFFSET_PC 0x8
#define OFFSET_I0 0x10
#define OFFSET_I1 0x18
#define OFFSET_I2 0x20
#define OFFSET_I3 0x28
#define OFFSET_I4 0x30
#define OFFSET_I5 0x38
#define OFFSET_FP 0x40
#define OFFSET_I7 0x48
#define OFFSET_L0 0x50
#define OFFSET_L1 0x58
#define OFFSET_L2 0x60
#define OFFSET_L3 0x68
#define OFFSET_L4 0x70
#define OFFSET_L5 0x78
#define OFFSET_L6 0x80
#define OFFSET_L7 0x88
 
#ifndef KERNEL
# define OFFSET_TP 0x90
#endif
 
#ifdef __ASM__
 
.macro CONTEXT_SAVE_ARCH_CORE ctx:req
stx %sp, [\ctx + OFFSET_SP]
stx %o7, [\ctx + OFFSET_PC]
stx %i0, [\ctx + OFFSET_I0]
stx %i1, [\ctx + OFFSET_I1]
stx %i2, [\ctx + OFFSET_I2]
stx %i3, [\ctx + OFFSET_I3]
stx %i4, [\ctx + OFFSET_I4]
stx %i5, [\ctx + OFFSET_I5]
stx %fp, [\ctx + OFFSET_FP]
stx %i7, [\ctx + OFFSET_I7]
stx %l0, [\ctx + OFFSET_L0]
stx %l1, [\ctx + OFFSET_L1]
stx %l2, [\ctx + OFFSET_L2]
stx %l3, [\ctx + OFFSET_L3]
stx %l4, [\ctx + OFFSET_L4]
stx %l5, [\ctx + OFFSET_L5]
stx %l6, [\ctx + OFFSET_L6]
stx %l7, [\ctx + OFFSET_L7]
#ifndef KERNEL
stx %g7, [\ctx + OFFSET_TP]
#endif
.endm
 
.macro CONTEXT_RESTORE_ARCH_CORE ctx:req
ldx [\ctx + OFFSET_SP], %sp
ldx [\ctx + OFFSET_PC], %o7
ldx [\ctx + OFFSET_I0], %i0
ldx [\ctx + OFFSET_I1], %i1
ldx [\ctx + OFFSET_I2], %i2
ldx [\ctx + OFFSET_I3], %i3
ldx [\ctx + OFFSET_I4], %i4
ldx [\ctx + OFFSET_I5], %i5
ldx [\ctx + OFFSET_FP], %fp
ldx [\ctx + OFFSET_I7], %i7
ldx [\ctx + OFFSET_L0], %l0
ldx [\ctx + OFFSET_L1], %l1
ldx [\ctx + OFFSET_L2], %l2
ldx [\ctx + OFFSET_L3], %l3
ldx [\ctx + OFFSET_L4], %l4
ldx [\ctx + OFFSET_L5], %l5
ldx [\ctx + OFFSET_L6], %l6
ldx [\ctx + OFFSET_L7], %l7
#ifndef KERNEL
ldx [\ctx + OFFSET_TP], %g7
#endif
.endm
 
#endif /* __ASM__ */
 
#endif
/tags/0.4.0/kernel/arch/sparc64/include/byteorder.h
0,0 → 1,43
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_BYTEORDER_H_
#define KERN_sparc64_BYTEORDER_H_
 
#define ARCH_IS_BIG_ENDIAN
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/stack.h
0,0 → 1,72
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_STACK_H_
#define KERN_sparc64_STACK_H_
 
#define STACK_ITEM_SIZE 8
 
/** According to SPARC Compliance Definition, every stack frame is 16-byte aligned. */
#define STACK_ALIGNMENT 16
 
/**
* 16-extended-word save area for %i[0-7] and %l[0-7] registers.
*/
#define STACK_WINDOW_SAVE_AREA_SIZE (16 * STACK_ITEM_SIZE)
 
/**
* Six extended words for first six arguments.
*/
#define STACK_ARG_SAVE_AREA_SIZE (6 * STACK_ITEM_SIZE)
 
/**
* By convention, the actual top of the stack is %sp + STACK_BIAS.
*/
#define STACK_BIAS 2047
 
/*
* Offsets of arguments on stack.
*/
#define STACK_ARG0 0
#define STACK_ARG1 8
#define STACK_ARG2 16
#define STACK_ARG3 24
#define STACK_ARG4 32
#define STACK_ARG5 40
#define STACK_ARG6 48
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/interrupt.h
0,0 → 1,76
/*
* Copyright (c) 2005 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 sparc64interrupt sparc64
* @ingroup interrupt
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_INTERRUPT_H_
#define KERN_sparc64_INTERRUPT_H_
 
#include <arch/types.h>
#include <arch/regdef.h>
 
#define IVT_ITEMS 15
#define IVT_FIRST 1
 
/* This needs to be defined for inter-architecture API portability. */
#define VECTOR_TLB_SHOOTDOWN_IPI 0
 
enum {
IPI_TLB_SHOOTDOWN = VECTOR_TLB_SHOOTDOWN_IPI
};
 
typedef struct {
uint64_t tnpc;
uint64_t tpc;
uint64_t tstate;
} istate_t;
 
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr)
{
istate->tpc = retaddr;
}
 
static inline int istate_from_uspace(istate_t *istate)
{
return !(istate->tstate & TSTATE_PRIV_BIT);
}
 
static inline unative_t istate_get_pc(istate_t *istate)
{
return istate->tpc;
}
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/boot/boot.h
0,0 → 1,92
/*
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_BOOT_H_
#define KERN_sparc64_BOOT_H_
 
#define VMA 0x400000
#define LMA VMA
 
#ifndef __ASM__
#ifndef __LINKER__
 
#include <config.h>
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
 
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
typedef struct {
void * addr;
uint32_t size;
} utask_t;
 
typedef struct {
uint32_t count;
utask_t tasks[TASKMAP_MAX_RECORDS];
} taskmap_t;
 
typedef struct {
uintptr_t start;
uint32_t size;
} memzone_t;
 
typedef struct {
uint32_t total;
uint32_t count;
memzone_t zones[MEMMAP_MAX_RECORDS];
} memmap_t;
 
/** Bootinfo structure.
*
* Must be in sync with bootinfo structure used by the boot loader.
*/
typedef struct {
uintptr_t physmem_start;
taskmap_t taskmap;
memmap_t memmap;
ballocs_t ballocs;
ofw_tree_node_t *ofw_root;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
 
#endif
#endif
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/sparc64.h
0,0 → 1,45
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_SPARC64_H_
#define KERN_sparc64_SPARC64_H_
 
#include <interrupt.h>
 
extern void interrupt_register(int n, const char *name, iroutine f);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/fpu_context.h
0,0 → 1,51
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_FPU_CONTEXT_H_
#define KERN_sparc64_FPU_CONTEXT_H_
 
#include <arch/types.h>
 
#define ARCH_HAS_FPU
#define FPU_CONTEXT_ALIGN 8
 
typedef struct {
uint64_t d[32];
uint64_t fsr;
} fpu_context_t;
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/context.h
0,0 → 1,84
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CONTEXT_H_
#define KERN_sparc64_CONTEXT_H_
 
#include <arch/stack.h>
#include <arch/types.h>
#include <align.h>
 
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE
 
#ifdef context_set
#undef context_set
#endif
 
#define context_set(c, _pc, stack, size) \
(c)->pc = ((uintptr_t) _pc) - 8; \
(c)->sp = ((uintptr_t) stack) + ALIGN_UP((size), \
STACK_ALIGNMENT) - (STACK_BIAS + SP_DELTA); \
(c)->fp = -STACK_BIAS
 
/*
* Save only registers that must be preserved across
* function calls.
*/
typedef struct {
uintptr_t sp; /* %o6 */
uintptr_t pc; /* %o7 */
uint64_t i0;
uint64_t i1;
uint64_t i2;
uint64_t i3;
uint64_t i4;
uint64_t i5;
uintptr_t fp; /* %i6 */
uintptr_t i7;
uint64_t l0;
uint64_t l1;
uint64_t l2;
uint64_t l3;
uint64_t l4;
uint64_t l5;
uint64_t l6;
uint64_t l7;
ipl_t ipl;
} context_t;
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/cycle.h
0,0 → 1,48
/*
* Copyright (c) 2006 Martin Decky
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CYCLE_H_
#define KERN_sparc64_CYCLE_H_
 
#include <arch/asm.h>
 
static inline uint64_t get_cycle(void)
{
return tick_read();
}
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/console.h
0,0 → 1,44
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CONSOLE_H_
#define KERN_sparc64_CONSOLE_H_
 
extern void kkbdpoll(void *arg);
extern void standalone_sparc64_console_init(void);
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/elf.h
0,0 → 1,45
/*
* Copyright (c) 2006 Sergey Bondari
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_ELF_H_
#define KERN_sparc64_ELF_H_
 
#define ELF_MACHINE EM_SPARCV9
#define ELF_DATA_ENCODING ELFDATA2MSB
#define ELF_CLASS ELFCLASS64
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/arg.h
0,0 → 1,43
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_ARG_H_
#define KERN_sparc64_ARG_H_
 
#include <stdarg.h>
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/proc/task.h
0,0 → 1,47
/*
* 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 sparc64proc
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_TASK_H_
#define KERN_sparc64_TASK_H_
 
typedef struct {
} task_arch_t;
 
#define task_create_arch(t)
#define task_destroy_arch(t)
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/proc/thread.h
0,0 → 1,49
/*
* Copyright (c) 2005 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 sparc64proc
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_THREAD_H_
#define KERN_sparc64_THREAD_H_
 
#include <arch/types.h>
#include <arch/arch.h>
 
typedef struct {
/** Buffer for register windows with userspace content. */
uint8_t *uspace_window_buffer;
} thread_arch_t;
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/faddr.h
0,0 → 1,45
/*
* Copyright (c) 2005 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_FADDR_H_
#define KERN_sparc64_FADDR_H_
 
#include <arch/types.h>
 
#define FADDR(fptr) ((uintptr_t) (fptr))
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/include/debug.h
0,0 → 1,41
/*
* Copyright (c) 2005 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 sparc64debug
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_DEBUG_H_
#define KERN_sparc64_DEBUG_H_
 
#endif
 
/** @}
*/
/tags/0.4.0/kernel/arch/sparc64/_link.ld.in
0,0 → 1,48
/** SPARC64 linker script
*
* It is ELF format, but its only section looks like this:
* kernel text
* kernel data
*
*/
 
#include <arch/boot/boot.h>
 
ENTRY(kernel_image_start)
 
SECTIONS {
.image VMA: AT (LMA) {
ktext_start = .;
*(K_TEXT_START)
*(.text);
ktext_end = .;
kdata_start = .;
*(K_DATA_START)
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
. = ALIGN(8);
hardcoded_ktext_size = .;
QUAD(ktext_end - ktext_start);
hardcoded_kdata_size = .;
QUAD(kdata_end - kdata_start);
hardcoded_load_address = .;
QUAD(VMA);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
kdata_end = .;
}
/DISCARD/ : {
*(*);
}
 
}