/kernel/trunk/arch/ia64/src/ski/ski.c |
---|
0,0 → 1,157 |
/* |
* 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/ski/ski.h> |
#include <console/console.h> |
#include <console/chardev.h> |
static chardev_t ski_console; |
static bool kb_disable; |
static void ski_putchar(chardev_t *d, const char ch); |
static __s32 ski_getchar(void); |
/** Display character on debug console |
* |
* Use SSC (Simulator System Call) to |
* display character on debug console. |
* |
* @param d Character device. |
* @param ch Character to be printed. |
*/ |
void ski_putchar(chardev_t *d, const char ch) |
{ |
__asm__ volatile ( |
"mov r15=%0\n" |
"mov r32=%1\n" /* r32 is in0 */ |
"break 0x80000\n" /* modifies r8 */ |
: |
: "i" (SKI_PUTCHAR), "r" (ch) |
: "r15", "in0", "r8" |
); |
if (ch == '\n') |
ski_putchar(d, '\r'); |
} |
/** Ask debug console if a key was pressed. |
* |
* Use SSC (Simulator System Call) to |
* get character from debug console. |
* |
* This call is non-blocking. |
* |
* @return ASCII code of pressed key or 0 if no key pressed. |
*/ |
__s32 ski_getchar(void) |
{ |
__u64 ch; |
__asm__ volatile ( |
"mov r15=%1\n" |
"break 0x80000;;\n" /* modifies r8 */ |
"mov %0=r8;;\n" |
: "=r" (ch) |
: "i" (SKI_GETCHAR) |
: "r15", "r8" |
); |
return (__s32) ch; |
} |
/** |
* This is a blocking wrapper for ski_getchar(). |
* To be used when the kernel crashes. |
*/ |
static char ski_getchar_blocking(chardev_t *d) |
{ |
int ch; |
while(!(ch=ski_getchar())) |
; |
if(ch == '\r') |
ch = '\n'; |
return (char) ch; |
} |
/** Ask keyboard if a key was pressed. */ |
void poll_keyboard(void) |
{ |
char ch; |
if (kb_disable) |
return; |
ch = ski_getchar(); |
if(ch == '\r') |
ch = '\n'; |
if (ch) |
chardev_push_character(&ski_console, ch); |
} |
/* Called from getc(). */ |
static void ski_kb_enable(chardev_t *d) |
{ |
kb_disable = false; |
} |
/* Called from getc(). */ |
static void ski_kb_disable(chardev_t *d) |
{ |
kb_disable = true; |
} |
static chardev_operations_t ski_ops = { |
.resume = ski_kb_enable, |
.suspend = ski_kb_disable, |
.write = ski_putchar, |
.read = ski_getchar_blocking |
}; |
/** Initialize debug console |
* |
* Issue SSC (Simulator System Call) to |
* to open debug console. |
*/ |
void ski_init_console(void) |
{ |
__asm__ volatile ( |
"mov r15=%0\n" |
"break 0x80000\n" |
: |
: "i" (SKI_INIT_CONSOLE) |
: "r15", "r8" |
); |
chardev_initialize("ski_console", &ski_console, &ski_ops); |
stdin = &ski_console; |
stdout = &ski_console; |
} |
/kernel/trunk/arch/ia64/src/start.S |
---|
0,0 → 1,148 |
# |
# 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/register.h> |
#include <arch/mm/page.h> |
#include <arch/mm/asid.h> |
#include <mm/asid.h> |
#define RR_MASK (0xFFFFFFFF00000002) |
#define RID_SHIFT 8 |
#define PS_SHIFT 2 |
#define KERNEL_TRANSLATION_I 0x0010000000000661 |
#define KERNEL_TRANSLATION_D 0x0010000000000661 |
.section K_TEXT_START |
.global kernel_image_start |
stack0: |
kernel_image_start: |
.auto |
# Fill TR.i and TR.d using Region Register #VRN_KERNEL |
movl r8=(VRN_KERNEL<<VRN_SHIFT) |
mov r9=rr[r8] |
movl r10=(RR_MASK) |
and r9=r10,r9 |
movl r10=((ASID2RID(ASID_KERNEL,VRN_KERNEL)<<RID_SHIFT)|(KERNEL_PAGE_WIDTH<<PS_SHIFT)) |
or r9=r10,r9 |
mov rr[r8]=r9 |
movl r8=(VRN_KERNEL<<VRN_SHIFT) |
mov cr.ifa=r8 |
movl r10=(KERNEL_PAGE_WIDTH<<PS_SHIFT) |
mov cr.itir=r10 |
movl r10=(KERNEL_TRANSLATION_I) |
itr.i itr[r0]=r10 |
movl r10=(KERNEL_TRANSLATION_D) |
itr.d dtr[r0]=r10 |
# initialize PSR |
mov psr.l = r0 |
srlz.i |
srlz.d |
movl r10=(PSR_DT_MASK|PSR_RT_MASK|PSR_IT_MASK|PSR_IC_MASK) /* Enable paging */ |
mov r9=psr |
or r10=r10,r9 |
mov cr.ipsr=r10 |
mov cr.ifs=r0 |
movl r8=paging_start |
mov cr.iip=r8 |
srlz.d |
srlz.i |
.explicit |
/* |
* Return From Interupt is the only the way to fill upper half word of PSR. |
*/ |
rfi;; |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
.global paging_start |
paging_start: |
/* |
* Now we are paging. |
*/ |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
{nop 0;;} |
# switch to register bank 1 |
bsw.1 |
# initialize register stack |
mov ar.rsc = r0 |
movl r8=(VRN_KERNEL<<VRN_SHIFT) ;; |
mov ar.bspstore = r8 |
loadrs |
# initialize memory stack to some sane value |
movl r12 = stack0;; |
add r12 = - 16, r12 /* allocate a scratch area on the stack */ |
# initialize gp (Global Pointer) register |
movl r1 = _hardcoded_load_address ;; |
/* |
* Initialize hardcoded_* variables. |
*/ |
movl r14 = _hardcoded_ktext_size |
movl r15 = _hardcoded_kdata_size |
movl r16 = _hardcoded_load_address |
addl r17 = @gprel(hardcoded_ktext_size), gp |
addl r18 = @gprel(hardcoded_kdata_size), gp |
addl r19 = @gprel(hardcoded_load_address), gp |
;; |
st8 [r17] = r14 |
st8 [r18] = r15 |
st8 [r19] = r16 |
movl r18=main_bsp ;; |
mov b1=r18 ;; |
br.call.sptk.many b0=b1 |
0: |
br 0b |
/kernel/trunk/arch/ia64/src/mm/page.c |
---|
0,0 → 1,251 |
/* |
* Copyright (C) 2006 Jakub Jermar |
* Copyright (C) 2006 Jakub Vana |
* 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/mm/page.h> |
#include <genarch/mm/page_ht.h> |
#include <mm/asid.h> |
#include <arch/mm/asid.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <print.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
#include <config.h> |
#include <panic.h> |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <memstr.h> |
static void set_environment(void); |
/** Initialize ia64 virtual address translation subsystem. */ |
void page_arch_init(void) |
{ |
page_mapping_operations = &ht_mapping_operations; |
pk_disable(); |
set_environment(); |
} |
/** Initialize VHPT and region registers. */ |
void set_environment(void) |
{ |
region_register rr; |
pta_register pta; |
int i; |
/* |
* First set up kernel region register. |
* This action is redundand (see start.S) but I would to keep it to make sure that |
*no unexpected changes will be made. |
*/ |
rr.word = rr_read(VRN_KERNEL); |
rr.map.ve = 0; /* disable VHPT walker */ |
rr.map.ps = PAGE_WIDTH; |
rr.map.rid = ASID2RID(ASID_KERNEL,VRN_KERNEL); |
rr_write(VRN_KERNEL, rr.word); |
srlz_i(); |
srlz_d(); |
/* |
* And invalidate the rest of region register. |
*/ |
for(i = 0; i < REGION_REGISTERS; i++) { |
/* skip kernel rr */ |
if (i == VRN_KERNEL) |
continue; |
rr.word == rr_read(i); |
rr.map.ve = 0; /* disable VHPT walker */ |
rr.map.rid = ASID2RID(ASID_INVALID,i); |
rr_write(i, rr.word); |
srlz_i(); |
srlz_d(); |
} |
/* |
* Set up PTA register. |
*/ |
pta.word = pta_read(); |
pta.map.ve = 0; /* disable VHPT walker */ |
pta.map.vf = 1; /* large entry format */ |
pta.map.size = VHPT_WIDTH; |
pta.map.base = VHPT_BASE >> PTA_BASE_SHIFT; |
pta_write(pta.word); |
srlz_i(); |
srlz_d(); |
return ; |
} |
/** Calculate address of collision chain from VPN and ASID. |
* |
* Interrupts must be disabled. |
* |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* |
* @return VHPT entry address. |
*/ |
vhpt_entry_t *vhpt_hash(__address page, asid_t asid) |
{ |
region_register rr_save, rr; |
index_t vrn; |
rid_t rid; |
vhpt_entry_t *v; |
vrn = page >> VRN_SHIFT; |
rid = ASID2RID(asid, vrn); |
rr_save.word = rr_read(vrn); |
if (rr_save.map.rid == rid) { |
/* |
* The RID is already in place, compute thash and return. |
*/ |
v = (vhpt_entry_t *) thash(page); |
return v; |
} |
/* |
* The RID must be written to some region register. |
* To speed things up, register indexed by vrn is used. |
*/ |
rr.word = rr_save.word; |
rr.map.rid = rid; |
rr_write(vrn, rr.word); |
srlz_i(); |
v = (vhpt_entry_t *) thash(page); |
rr_write(vrn, rr_save.word); |
srlz_i(); |
srlz_d(); |
return v; |
} |
/** Compare ASID and VPN against PTE. |
* |
* Interrupts must be disabled. |
* |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* |
* @return True if page and asid match the page and asid of t, false otherwise. |
*/ |
bool vhpt_compare(__address page, asid_t asid, vhpt_entry_t *v) |
{ |
region_register rr_save, rr; |
index_t vrn; |
rid_t rid; |
bool match; |
ASSERT(v); |
vrn = page >> VRN_SHIFT; |
rid = ASID2RID(asid, vrn); |
rr_save.word = rr_read(vrn); |
if (rr_save.map.rid == rid) { |
/* |
* The RID is already in place, compare ttag with t and return. |
*/ |
return ttag(page) == v->present.tag.tag_word; |
} |
/* |
* The RID must be written to some region register. |
* To speed things up, register indexed by vrn is used. |
*/ |
rr.word = rr_save.word; |
rr.map.rid = rid; |
rr_write(vrn, rr.word); |
srlz_i(); |
match = (ttag(page) == v->present.tag.tag_word); |
rr_write(vrn, rr_save.word); |
srlz_i(); |
srlz_d(); |
return match; |
} |
/** Set up one VHPT entry. |
* |
* @param t VHPT entry to be set up. |
* @param page Virtual address of the page mapped by the entry. |
* @param asid Address space identifier of the address space to which page belongs. |
* @param frame Physical address of the frame to wich page is mapped. |
* @param flags Different flags for the mapping. |
*/ |
void vhpt_set_record(vhpt_entry_t *v, __address page, asid_t asid, __address frame, int flags) |
{ |
region_register rr_save, rr; |
index_t vrn; |
rid_t rid; |
__u64 tag; |
ASSERT(v); |
vrn = page >> VRN_SHIFT; |
rid = ASID2RID(asid, vrn); |
/* |
* Compute ttag. |
*/ |
rr_save.word = rr_read(vrn); |
rr.word = rr_save.word; |
rr.map.rid = rid; |
rr_write(vrn, rr.word); |
srlz_i(); |
tag = ttag(page); |
rr_write(vrn, rr_save.word); |
srlz_i(); |
srlz_d(); |
/* |
* Clear the entry. |
*/ |
v->word[0] = 0; |
v->word[1] = 0; |
v->word[2] = 0; |
v->word[3] = 0; |
v->present.p = true; |
v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE; |
v->present.a = false; /* not accessed */ |
v->present.d = false; /* not dirty */ |
v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL; |
v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ; |
v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0; |
v->present.ppn = frame >> PPN_SHIFT; |
v->present.ed = false; /* exception not deffered */ |
v->present.ps = PAGE_WIDTH; |
v->present.key = 0; |
v->present.tag.tag_word = tag; |
} |
/kernel/trunk/arch/ia64/src/mm/as.c |
---|
0,0 → 1,38 |
/* |
* 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/mm/as.h> |
#include <genarch/mm/as_ht.h> |
#include <genarch/mm/asid_fifo.h> |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_ht_operations; |
asid_fifo_init(); |
} |
/kernel/trunk/arch/ia64/src/mm/frame.c |
---|
0,0 → 1,56 |
/* |
* 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/mm/frame.h> |
#include <mm/frame.h> |
#include <config.h> |
#include <panic.h> |
/* |
* This is Ski-specific and certainly not sufficient |
* for real ia64 systems that provide memory map. |
*/ |
#define ROM_BASE 0xa0000 |
#define ROM_SIZE (384*1024) |
void frame_arch_init(void) |
{ |
zone_create(0, config.memory_size >> FRAME_WIDTH, 1, 0); |
/* |
* Workaround to prevent slab allocator from allocating frame 0. |
* Remove the following statement when the kernel is no longer |
* identity mapped. |
*/ |
frame_mark_unavailable(0, 1); |
/* |
* Blacklist ROM regions. |
*/ |
frame_mark_unavailable(ADDR2PFN(ROM_BASE), ROM_SIZE >> FRAME_WIDTH); |
} |
/kernel/trunk/arch/ia64/src/mm/tlb.c |
---|
0,0 → 1,287 |
/* |
* 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. |
*/ |
/* |
* TLB management. |
*/ |
#include <mm/tlb.h> |
#include <arch/mm/tlb.h> |
#include <arch/barrier.h> |
/** Invalidate all TLB entries. */ |
void tlb_invalidate_all(void) |
{ |
/* TODO */ |
} |
/** Invalidate entries belonging to an address space. |
* |
* @param asid Address space identifier. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
/* TODO */ |
} |
void tlb_fill_data(__address va,asid_t asid,tlb_entry_t entry) |
{ |
region_register rr; |
if(!(entry.not_present.p)) return; |
rr.word=rr_read(VA_REGION(va)); |
if(rr.map.rid==ASID2RID(asid,VA_REGION(va))) |
{ |
asm volatile |
( |
"srlz.i;;\n" |
"srlz.d;;\n" |
"mov r8=psr;;\n" |
"and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
"mov psr.l=r9;;\n" |
"srlz.d;;\n" |
"srlz.i;;\n" |
"mov cr.ifa=%1\n" /*va*/ |
"mov cr.itir=%2;;\n" /*entry.word[1]*/ |
"itc.d %3;;\n" /*entry.word[0]*/ |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
:"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]) |
:"r8","r9" |
); |
} |
else |
{ |
region_register rr0; |
rr0=rr; |
rr0.map.rid=ASID2RID(asid,VA_REGION(va)); |
rr_write(VA_REGION(va),rr0.word); |
srlz_d(); |
asm volatile |
( |
"mov r8=psr;;\n" |
"and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
"mov psr.l=r9;;\n" |
"srlz.d;;\n" |
"mov cr.ifa=%1\n" /*va*/ |
"mov cr.itir=%2;;\n" /*entry.word[1]*/ |
"itc.d %3;;\n" /*entry.word[0]*/ |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
:"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]) |
:"r8","r9" |
); |
rr_write(VA_REGION(va),rr.word); |
} |
} |
void tlb_fill_code(__address va,asid_t asid,tlb_entry_t entry) |
{ |
region_register rr; |
if(!(entry.not_present.p)) return; |
rr.word=rr_read(VA_REGION(va)); |
if(rr.map.rid==ASID2RID(asid,VA_REGION(va))) |
{ |
asm volatile |
( |
"srlz.i;;\n" |
"srlz.d;;\n" |
"mov r8=psr;;\n" |
"and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
"mov psr.l=r9;;\n" |
"srlz.d;;\n" |
"srlz.i;;\n" |
"mov cr.ifa=%1\n" /*va*/ |
"mov cr.itir=%2;;\n" /*entry.word[1]*/ |
"itc.i %3;;\n" /*entry.word[0]*/ |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
:"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]) |
:"r8","r9" |
); |
} |
else |
{ |
region_register rr0; |
rr0=rr; |
rr0.map.rid=ASID2RID(asid,VA_REGION(va)); |
rr_write(VA_REGION(va),rr0.word); |
srlz_d(); |
asm volatile |
( |
"mov r8=psr;;\n" |
"and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
"mov psr.l=r9;;\n" |
"srlz.d;;\n" |
"mov cr.ifa=%1\n" /*va*/ |
"mov cr.itir=%2;;\n" /*entry.word[1]*/ |
"itc.i %3;;\n" /*entry.word[0]*/ |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
:"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]) |
:"r8","r9" |
); |
rr_write(VA_REGION(va),rr.word); |
} |
} |
void tlb_fill_data_tr(__u64 tr,__address va,asid_t asid,tlb_entry_t entry) |
{ |
region_register rr; |
if(!(entry.not_present.p)) return; |
rr.word=rr_read(VA_REGION(va)); |
if(rr.map.rid==ASID2RID(asid,VA_REGION(va))) |
{ |
asm volatile |
( |
"srlz.i;;\n" |
"srlz.d;;\n" |
"mov r8=psr;;\n" |
"and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
"mov psr.l=r9;;\n" |
"srlz.d;;\n" |
"srlz.i;;\n" |
"mov cr.ifa=%1\n" /*va*/ |
"mov cr.itir=%2;;\n" /*entry.word[1]*/ |
"itr.d dtr[%4]=%3;;\n" /*entry.word[0]*/ |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
:"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr) |
:"r8","r9" |
); |
} |
else |
{ |
region_register rr0; |
rr0=rr; |
rr0.map.rid=ASID2RID(asid,VA_REGION(va)); |
rr_write(VA_REGION(va),rr0.word); |
srlz_d(); |
asm volatile |
( |
"mov r8=psr;;\n" |
"and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
"mov psr.l=r9;;\n" |
"srlz.d;;\n" |
"mov cr.ifa=%1\n" /*va*/ |
"mov cr.itir=%2;;\n" /*entry.word[1]*/ |
"itr.d dtr[%4]=%3;;\n" /*entry.word[0]*/ |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
:"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr) |
:"r8","r9" |
); |
rr_write(VA_REGION(va),rr.word); |
} |
} |
void tlb_fill_code_tr(__u64 tr,__address va,asid_t asid,tlb_entry_t entry) |
{ |
region_register rr; |
if(!(entry.not_present.p)) return; |
rr.word=rr_read(VA_REGION(va)); |
if(rr.map.rid==ASID2RID(asid,VA_REGION(va))) |
{ |
asm volatile |
( |
"srlz.i;;\n" |
"srlz.d;;\n" |
"mov r8=psr;;\n" |
"and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
"mov psr.l=r9;;\n" |
"srlz.d;;\n" |
"srlz.i;;\n" |
"mov cr.ifa=%1\n" /*va*/ |
"mov cr.itir=%2;;\n" /*entry.word[1]*/ |
"itr.i itr[%4]=%3;;\n" /*entry.word[0]*/ |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
:"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr) |
:"r8","r9" |
); |
} |
else |
{ |
region_register rr0; |
rr0=rr; |
rr0.map.rid=ASID2RID(asid,VA_REGION(va)); |
rr_write(VA_REGION(va),rr0.word); |
srlz_d(); |
asm volatile |
( |
"mov r8=psr;;\n" |
"and r9=r8,%0;;\n" /*(~PSR_IC_MASK)*/ |
"mov psr.l=r9;;\n" |
"srlz.d;;\n" |
"mov cr.ifa=%1\n" /*va*/ |
"mov cr.itir=%2;;\n" /*entry.word[1]*/ |
"itr.i itr[%4]=%3;;\n" /*entry.word[0]*/ |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
:"r"(~PSR_IC_MASK),"r"(va),"r"(entry.word[1]),"r"(entry.word[0]),"r"(tr) |
:"r8","r9" |
); |
rr_write(VA_REGION(va),rr.word); |
} |
} |
/kernel/trunk/arch/ia64/src/asm.S |
---|
0,0 → 1,48 |
# |
# 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 memcpy |
memcpy: |
br _memcpy |
.global memsetb |
memsetb: |
br _memsetb |
.global cpu_halt |
cpu_halt: |
br cpu_halt |
.global panic_printf |
panic_printf: |
{ |
br.call.sptk.many b0=printf |
} |
br halt |
/kernel/trunk/arch/ia64/src/putchar.c |
---|
0,0 → 1,35 |
/* |
* 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 <putchar.h> |
#include <arch/ski/ski.h> |
void putchar(const char ch) |
{ |
ski_write(ch); |
} |
/kernel/trunk/arch/ia64/src/interrupt.c |
---|
0,0 → 1,204 |
/* |
* Copyright (C) 2005 Jakub Jermar |
* Copyright (C) 2005 Jakub Vana |
* 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/interrupt.h> |
#include <panic.h> |
#include <print.h> |
#include <console/console.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <arch/register.h> |
#include <arch/drivers/it.h> |
#include <arch.h> |
#include <symtab.h> |
#include <debug.h> |
#define VECTORS_64_BUNDLE 20 |
#define VECTORS_16_BUNDLE 48 |
#define VECTORS_16_BUNDLE_START 0x5000 |
#define VECTOR_MAX 0x7f00 |
#define BUNDLE_SIZE 16 |
char *vector_names_64_bundle[VECTORS_64_BUNDLE] = { |
"VHPT Translation vector", |
"Instruction TLB vector", |
"Data TLB vector", |
"Alternate Instruction TLB vector", |
"Alternate Data TLB vector", |
"Data Nested TLB vector", |
"Instruction Key Miss vector", |
"Data Key Miss vector", |
"Dirty-Bit vector", |
"Instruction Access-Bit vector", |
"Data Access-Bit vector" |
"Break Instruction vector", |
"External Interrupt vector" |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved" |
}; |
char *vector_names_16_bundle[VECTORS_16_BUNDLE] = { |
"Page Not Present vector", |
"Key Permission vector", |
"Instruction Access rights vector", |
"Data Access Rights vector", |
"General Exception vector", |
"Disabled FP-Register vector", |
"NaT Consumption vector", |
"Speculation vector", |
"Reserved", |
"Debug vector", |
"Unaligned Reference vector", |
"Unsupported Data Reference vector", |
"Floating-point Fault vector", |
"Floating-point Trap vector", |
"Lower-Privilege Transfer Trap vector", |
"Taken Branch Trap vector", |
"Single STep Trap vector", |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved", |
"Reserved", |
"IA-32 Exception vector", |
"IA-32 Intercept vector", |
"IA-32 Interrupt vector", |
"Reserved", |
"Reserved", |
"Reserved" |
}; |
static char *vector_to_string(__u16 vector); |
static void dump_interrupted_context(struct exception_regdump *pstate); |
char *vector_to_string(__u16 vector) |
{ |
ASSERT(vector <= VECTOR_MAX); |
if (vector >= VECTORS_16_BUNDLE_START) |
return vector_names_16_bundle[(vector-VECTORS_16_BUNDLE_START)/(16*BUNDLE_SIZE)]; |
else |
return vector_names_64_bundle[vector/(64*BUNDLE_SIZE)]; |
} |
void dump_interrupted_context(struct exception_regdump *pstate) |
{ |
char *ifa, *iipa, *iip; |
ifa = get_symtab_entry(pstate->cr_ifa); |
iipa = get_symtab_entry(pstate->cr_iipa); |
iip = get_symtab_entry(pstate->cr_iip); |
putchar('\n'); |
printf("Interrupted context dump:\n"); |
printf("ar.bsp=%P\tar.bspstore=%P\n", pstate->ar_bsp, pstate->ar_bspstore); |
printf("ar.rnat=%Q\tar.rsc=%Q\n", pstate->ar_rnat, pstate->ar_rsc); |
printf("ar.ifs=%Q\tar.pfs=%Q\n", pstate->ar_ifs, pstate->ar_pfs); |
printf("cr.isr=%Q\tcr.ips=%Q\t\n", pstate->cr_isr.value, pstate->cr_ips); |
printf("cr.iip=%Q, #%d\t(%s)\n", pstate->cr_iip, pstate->cr_isr.ei ,iip ? iip : "?"); |
printf("cr.iipa=%Q\t(%s)\n", pstate->cr_iipa, iipa ? iipa : "?"); |
printf("cr.ifa=%Q\t(%s)\n", pstate->cr_ifa, ifa ? ifa : "?"); |
} |
void general_exception(__u64 vector, struct exception_regdump *pstate) |
{ |
char *desc = ""; |
dump_interrupted_context(pstate); |
switch (pstate->cr_isr.ge_code) { |
case GE_ILLEGALOP: |
desc = "Illegal Operation fault"; |
break; |
case GE_PRIVOP: |
desc = "Privileged Operation fault"; |
break; |
case GE_PRIVREG: |
desc = "Privileged Register fault"; |
break; |
case GE_RESREGFLD: |
desc = "Reserved Register/Field fault"; |
break; |
case GE_DISBLDISTRAN: |
desc = "Disabled Instruction Set Transition fault"; |
break; |
case GE_ILLEGALDEP: |
desc = "Illegal Dependency fault"; |
break; |
default: |
desc = "unknown"; |
break; |
} |
panic("General Exception (%s)\n", desc); |
} |
void break_instruction(__u64 vector, struct exception_regdump *pstate) |
{ |
dump_interrupted_context(pstate); |
panic("Break Instruction\n"); |
} |
void universal_handler(__u64 vector, struct exception_regdump *pstate) |
{ |
dump_interrupted_context(pstate); |
panic("Interruption: %W (%s)\n", (__u16) vector, vector_to_string(vector)); |
} |
void external_interrupt(__u64 vector, struct exception_regdump *pstate) |
{ |
cr_ivr_t ivr; |
ivr.value = ivr_read(); |
srlz_d(); |
switch(ivr.vector) { |
case INTERRUPT_TIMER: |
it_interrupt(); |
break; |
case INTERRUPT_SPURIOUS: |
printf("cpu%d: spurious interrupt\n", CPU->id); |
break; |
default: |
panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector); |
break; |
} |
} |
/kernel/trunk/arch/ia64/src/ia64.c |
---|
0,0 → 1,59 |
/* |
* 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.h> |
#include <arch/ski/ski.h> |
#include <arch/drivers/it.h> |
#include <arch/interrupt.h> |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <console/console.h> |
void arch_pre_mm_init(void) |
{ |
/* Set Interruption Vector Address (i.e. location of interruption vector table). */ |
iva_write((__address) &ivt); |
srlz_d(); |
ski_init_console(); |
it_init(); |
} |
void arch_post_mm_init(void) |
{ |
} |
void arch_pre_smp_init(void) |
{ |
} |
void arch_post_smp_init(void) |
{ |
} |
/kernel/trunk/arch/ia64/src/drivers/it.c |
---|
0,0 → 1,69 |
/* |
* 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. |
*/ |
/** Interval Timer driver. */ |
#include <arch/drivers/it.h> |
#include <arch/ski/ski.h> |
#include <arch/interrupt.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <time/clock.h> |
/** Initialize Interval Timer. */ |
void it_init(void) |
{ |
cr_itv_t itv; |
/* initialize Interval Timer external interrupt vector */ |
itv.value = itv_read(); |
itv.vector = INTERRUPT_TIMER; |
itv.m = 0; |
itv_write(itv.value); |
/* set Interval Timer Counter to zero */ |
itc_write(0); |
/* generate first Interval Timer interrupt in IT_DELTA ticks */ |
itm_write(IT_DELTA); |
/* propagate changes */ |
srlz_d(); |
} |
/** Process Interval Timer interrupt. */ |
void it_interrupt(void) |
{ |
eoi_write(EOI); |
itm_write(itc_read() + IT_DELTA); /* program next interruption */ |
srlz_d(); /* propagate changes */ |
clock(); |
poll_keyboard(); |
} |
/kernel/trunk/arch/ia64/src/dummy.s |
---|
0,0 → 1,52 |
# |
# 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 calibrate_delay_loop |
.global asm_delay_loop |
.global userspace |
.global before_thread_runs_arch |
.global cpu_sleep |
.global dummy |
.global fpu_enable |
.global fpu_disable |
.global fpu_init |
before_thread_runs_arch: |
userspace: |
calibrate_delay_loop: |
asm_delay_loop: |
cpu_sleep: |
fpu_init: |
fpu_enable: |
fpu_disable: |
dummy: |
br.ret.sptk.many b0 |
/kernel/trunk/arch/ia64/src/ivt.S |
---|
0,0 → 1,403 |
# |
# Copyright (C) 2005 Jakub Vana |
# 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/stack.h> |
#include <arch/register.h> |
#define STACK_ITEMS 12 |
#define STACK_FRAME_SIZE ((STACK_ITEMS*STACK_ITEM_SIZE) + STACK_SCRATCH_AREA_SIZE) |
#if (STACK_FRAME_SIZE % STACK_ALIGNMENT != 0) |
#error Memory stack must be 16-byte aligned. |
#endif |
/** Heavyweight interrupt handler |
* |
* This macro roughly follows steps from 1 to 19 described in |
* Intel Itanium Architecture Software Developer's Manual, Chapter 3.4.2. |
* |
* HEAVYWEIGHT_HANDLER macro must cram into 16 bundles (48 instructions). |
* This goal is achieved by using procedure calls after RSE becomes operational. |
* |
* Some steps are skipped (enabling and disabling interrupts). |
* Some steps are not fully supported yet (e.g. interruptions |
* from userspace and floating-point context). |
* |
* @param offs Offset from the beginning of IVT. |
* @param handler Interrupt handler address. |
*/ |
.macro HEAVYWEIGHT_HANDLER offs, handler=universal_handler |
.org ivt + \offs |
mov r24 = \offs |
movl r25 = \handler ;; |
mov ar.k0 = r24 |
mov ar.k1 = r25 |
br heavyweight_handler |
.endm |
.global heavyweight_handler |
heavyweight_handler: |
/* 1. copy interrupt registers into bank 0 */ |
mov r24 = cr.iip |
mov r25 = cr.ipsr |
mov r26 = cr.iipa |
mov r27 = cr.isr |
mov r28 = cr.ifa |
/* 2. preserve predicate register into bank 0 */ |
mov r29 = pr ;; |
/* 3. switch to kernel memory stack */ |
/* TODO: support interruptions from userspace */ |
/* assume kernel stack */ |
add r31 = -8, r12 ;; |
add r12 = -STACK_FRAME_SIZE, r12 |
/* 4. save registers in bank 0 into memory stack */ |
st8 [r31] = r29, -8 ;; /* save predicate registers */ |
st8 [r31] = r24, -8 ;; /* save cr.iip */ |
st8 [r31] = r25, -8 ;; /* save cr.ipsr */ |
st8 [r31] = r26, -8 ;; /* save cr.iipa */ |
st8 [r31] = r27, -8 ;; /* save cr.isr */ |
st8 [r31] = r28, -8 /* save cr.ifa */ |
/* 5. RSE switch from interrupted context */ |
mov r24 = ar.rsc |
mov r25 = ar.pfs |
cover |
mov r26 = cr.ifs |
st8 [r31] = r24, -8;; /* save ar.rsc */ |
st8 [r31] = r25, -8;; /* save ar.pfs */ |
st8 [r31] = r26, -8 /* save ar.ifs */ |
and r30 = ~3, r24 ;; |
mov ar.rsc = r30 ;; /* place RSE in enforced lazy mode */ |
mov r27 = ar.rnat |
mov r28 = ar.bspstore ;; |
/* assume kernel backing store */ |
/* mov ar.bspstore = r28 ;; */ |
mov r29 = ar.bsp |
st8 [r31] = r27, -8 ;; /* save ar.rnat */ |
st8 [r31] = r28, -8 ;; /* save ar.bspstore */ |
st8 [r31] = r29, -8 /* save ar.bsp */ |
mov ar.rsc = r24 /* restore RSE's setting */ |
/* steps 6 - 15 are done by heavyweight_handler_inner() */ |
mov r24 = b0 /* save b0 belonging to interrupted context */ |
mov r26 = ar.k0 |
mov r25 = ar.k1 |
br.call.sptk.many rp = heavyweight_handler_inner |
0: mov b0 = r24 /* restore b0 belonging to the interrupted context */ |
/* 16. RSE switch to interrupted context */ |
cover /* allocate zerro size frame (step 1 (from Intel Docs)) */ |
add r31 = STACK_SCRATCH_AREA_SIZE, r12 ;; |
mov r28 = ar.bspstore /* calculate loadrs (step 2) */ |
ld8 r29 = [r31], +8 ;; /* load ar.bsp */ |
sub r27 = r29 , r28 ;; |
shl r27 = r27, 16 |
mov r24 = ar.rsc ;; |
and r30 = ~3, r24 ;; |
or r24 = r30 , r27 ;; |
mov ar.rsc = r24 ;; /* place RSE in enforced lazy mode */ |
loadrs /* (step 3) */ |
ld8 r28 = [r31], +8 ;; /* load ar.bspstore */ |
ld8 r27 = [r31], +8 ;; /* load ar.rnat */ |
ld8 r26 = [r31], +8 ;; /* load cr.ifs */ |
ld8 r25 = [r31], +8 ;; /* load ar.pfs */ |
ld8 r24 = [r31], +8 ;; /* load ar.rsc */ |
/* mov ar.bspstore = r28 ;; */ /* (step 4) */ |
/* mov ar.rnat = r27 */ /* (step 5) */ |
mov ar.pfs = r25 /* (step 6) */ |
mov cr.ifs = r26 |
mov ar.rsc = r24 /* (step 7) */ |
/* 17. restore interruption state from memory stack */ |
ld8 r28 = [r31], +8 ;; /* load cr.ifa */ |
ld8 r27 = [r31], +8 ;; /* load cr.isr */ |
ld8 r26 = [r31], +8 ;; /* load cr.iipa */ |
ld8 r25 = [r31], +8 ;; /* load cr.ipsr */ |
ld8 r24 = [r31], +8 ;; /* load cr.iip */ |
mov cr.iip = r24 |
mov cr.ipsr = r25 |
mov cr.iipa = r26 |
mov cr.isr = r27 |
mov cr.ifa = r28 |
/* 18. restore predicate registers from memory stack */ |
ld8 r29 = [r31] , -8 ;; /* load predicate registers */ |
mov pr = r29 |
/* 19. return from interruption */ |
add r12 = STACK_FRAME_SIZE, r12 |
rfi ;; |
.global heavyweight_handler_inner |
heavyweight_handler_inner: |
/* |
* From this point, the rest of the interrupted context |
* will be preserved in stacked registers and backing store. |
*/ |
alloc loc0 = ar.pfs, 0, 47, 2, 0 ;; |
/* bank 0 is going to be shadowed, copy essential data from there */ |
mov loc1 = r24 /* b0 belonging to interrupted context */ |
mov loc2 = r25 |
mov out0 = r26 |
add out1 = STACK_SCRATCH_AREA_SIZE, r12 |
/* 6. switch to bank 1 and reenable PSR.ic */ |
ssm PSR_IC_MASK |
bsw.1 ;; |
srlz.d |
/* 7. preserve branch and application registers */ |
mov loc3 = ar.unat |
mov loc4 = ar.lc |
mov loc5 = ar.ec |
mov loc6 = ar.ccv |
mov loc7 = ar.csd |
mov loc8 = ar.ssd |
mov loc9 = b0 |
mov loc10 = b1 |
mov loc11 = b2 |
mov loc12 = b3 |
mov loc13 = b4 |
mov loc14 = b5 |
mov loc15 = b6 |
mov loc16 = b7 |
/* 8. preserve general and floating-point registers */ |
/* TODO: save floating-point context */ |
mov loc17 = r1 |
mov loc18 = r2 |
mov loc19 = r3 |
mov loc20 = r4 |
mov loc21 = r5 |
mov loc22 = r6 |
mov loc23 = r7 |
mov loc24 = r8 |
mov loc25 = r9 |
mov loc26 = r10 |
mov loc27 = r11 |
/* skip r12 (stack pointer) */ |
mov loc28 = r13 |
mov loc29 = r14 |
mov loc30 = r15 |
mov loc31 = r16 |
mov loc32 = r17 |
mov loc33 = r18 |
mov loc34 = r19 |
mov loc35 = r20 |
mov loc36 = r21 |
mov loc37 = r22 |
mov loc38 = r23 |
mov loc39 = r24 |
mov loc40 = r25 |
mov loc41 = r26 |
mov loc42 = r27 |
mov loc43 = r28 |
mov loc44 = r29 |
mov loc45 = r30 |
mov loc46 = r31 |
/* 9. skipped (will not enable interrupts) */ |
/* |
* ssm PSR_I_MASK |
* ;; |
* srlz.d |
*/ |
/* 10. call handler */ |
mov b1 = loc2 |
br.call.sptk.many b0 = b1 |
/* 11. return from handler */ |
0: |
/* 12. skipped (will not disable interrupts) */ |
/* |
* rsm PSR_I_MASK |
* ;; |
* srlz.d |
*/ |
/* 13. restore general and floating-point registers */ |
/* TODO: restore floating-point context */ |
mov r1 = loc17 |
mov r2 = loc18 |
mov r3 = loc19 |
mov r4 = loc20 |
mov r5 = loc21 |
mov r6 = loc22 |
mov r7 = loc23 |
mov r8 = loc24 |
mov r9 = loc25 |
mov r10 = loc26 |
mov r11 = loc27 |
/* skip r12 (stack pointer) */ |
mov r13 = loc28 |
mov r14 = loc29 |
mov r15 = loc30 |
mov r16 = loc31 |
mov r17 = loc32 |
mov r18 = loc33 |
mov r19 = loc34 |
mov r20 = loc35 |
mov r21 = loc36 |
mov r22 = loc37 |
mov r23 = loc38 |
mov r24 = loc39 |
mov r25 = loc40 |
mov r26 = loc41 |
mov r27 = loc42 |
mov r28 = loc43 |
mov r29 = loc44 |
mov r30 = loc45 |
mov r31 = loc46 |
/* 14. restore branch and application registers */ |
mov ar.unat = loc3 |
mov ar.lc = loc4 |
mov ar.ec = loc5 |
mov ar.ccv = loc6 |
mov ar.csd = loc7 |
mov ar.ssd = loc8 |
mov b0 = loc9 |
mov b1 = loc10 |
mov b2 = loc11 |
mov b3 = loc12 |
mov b4 = loc13 |
mov b5 = loc14 |
mov b6 = loc15 |
mov b7 = loc16 |
/* 15. disable PSR.ic and switch to bank 0 */ |
rsm PSR_IC_MASK |
bsw.0 ;; |
srlz.d |
mov r24 = loc1 |
mov ar.pfs = loc0 |
br.ret.sptk.many b0 |
.global ivt |
.align 32768 |
ivt: |
HEAVYWEIGHT_HANDLER 0x0000 |
HEAVYWEIGHT_HANDLER 0x0400 |
HEAVYWEIGHT_HANDLER 0x0800 |
HEAVYWEIGHT_HANDLER 0x0c00 |
HEAVYWEIGHT_HANDLER 0x1000 |
HEAVYWEIGHT_HANDLER 0x1400 |
HEAVYWEIGHT_HANDLER 0x1800 |
HEAVYWEIGHT_HANDLER 0x1c00 |
HEAVYWEIGHT_HANDLER 0x2000 |
HEAVYWEIGHT_HANDLER 0x2400 |
HEAVYWEIGHT_HANDLER 0x2800 |
HEAVYWEIGHT_HANDLER 0x2c00 break_instruction |
HEAVYWEIGHT_HANDLER 0x3000 external_interrupt /* For external interrupt, heavyweight handler is used. */ |
HEAVYWEIGHT_HANDLER 0x3400 |
HEAVYWEIGHT_HANDLER 0x3800 |
HEAVYWEIGHT_HANDLER 0x3c00 |
HEAVYWEIGHT_HANDLER 0x4000 |
HEAVYWEIGHT_HANDLER 0x4400 |
HEAVYWEIGHT_HANDLER 0x4800 |
HEAVYWEIGHT_HANDLER 0x4c00 |
HEAVYWEIGHT_HANDLER 0x5000 |
HEAVYWEIGHT_HANDLER 0x5100 |
HEAVYWEIGHT_HANDLER 0x5200 |
HEAVYWEIGHT_HANDLER 0x5300 |
HEAVYWEIGHT_HANDLER 0x5400 general_exception |
HEAVYWEIGHT_HANDLER 0x5500 |
HEAVYWEIGHT_HANDLER 0x5600 |
HEAVYWEIGHT_HANDLER 0x5700 |
HEAVYWEIGHT_HANDLER 0x5800 |
HEAVYWEIGHT_HANDLER 0x5900 |
HEAVYWEIGHT_HANDLER 0x5a00 |
HEAVYWEIGHT_HANDLER 0x5b00 |
HEAVYWEIGHT_HANDLER 0x5c00 |
HEAVYWEIGHT_HANDLER 0x5d00 |
HEAVYWEIGHT_HANDLER 0x5e00 |
HEAVYWEIGHT_HANDLER 0x5f00 |
HEAVYWEIGHT_HANDLER 0x6000 |
HEAVYWEIGHT_HANDLER 0x6100 |
HEAVYWEIGHT_HANDLER 0x6200 |
HEAVYWEIGHT_HANDLER 0x6300 |
HEAVYWEIGHT_HANDLER 0x6400 |
HEAVYWEIGHT_HANDLER 0x6500 |
HEAVYWEIGHT_HANDLER 0x6600 |
HEAVYWEIGHT_HANDLER 0x6700 |
HEAVYWEIGHT_HANDLER 0x6800 |
HEAVYWEIGHT_HANDLER 0x6900 |
HEAVYWEIGHT_HANDLER 0x6a00 |
HEAVYWEIGHT_HANDLER 0x6b00 |
HEAVYWEIGHT_HANDLER 0x6c00 |
HEAVYWEIGHT_HANDLER 0x6d00 |
HEAVYWEIGHT_HANDLER 0x6e00 |
HEAVYWEIGHT_HANDLER 0x6f00 |
HEAVYWEIGHT_HANDLER 0x7000 |
HEAVYWEIGHT_HANDLER 0x7100 |
HEAVYWEIGHT_HANDLER 0x7200 |
HEAVYWEIGHT_HANDLER 0x7300 |
HEAVYWEIGHT_HANDLER 0x7400 |
HEAVYWEIGHT_HANDLER 0x7500 |
HEAVYWEIGHT_HANDLER 0x7600 |
HEAVYWEIGHT_HANDLER 0x7700 |
HEAVYWEIGHT_HANDLER 0x7800 |
HEAVYWEIGHT_HANDLER 0x7900 |
HEAVYWEIGHT_HANDLER 0x7a00 |
HEAVYWEIGHT_HANDLER 0x7b00 |
HEAVYWEIGHT_HANDLER 0x7c00 |
HEAVYWEIGHT_HANDLER 0x7d00 |
HEAVYWEIGHT_HANDLER 0x7e00 |
HEAVYWEIGHT_HANDLER 0x7f00 |
/kernel/trunk/arch/ia64/src/cpu/cpu.c |
---|
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. |
*/ |
#include <cpu.h> |
#include <arch.h> |
#include <arch/register.h> |
#include <print.h> |
void cpu_arch_init(void) |
{ |
} |
void cpu_identify(void) |
{ |
CPU->arch.cpuid0 = cpuid_read(0); |
CPU->arch.cpuid1 = cpuid_read(1); |
CPU->arch.cpuid3.value = cpuid_read(3); |
} |
void cpu_print_report(cpu_t *m) |
{ |
char *family_str; |
char vendor[2*sizeof(__u64)+1]; |
*((__u64 *) &vendor[0*sizeof(__u64)]) = CPU->arch.cpuid0; |
*((__u64 *) &vendor[1*sizeof(__u64)]) = CPU->arch.cpuid1; |
vendor[sizeof(vendor)-1] = '\0'; |
switch(m->arch.cpuid3.family) { |
case FAMILY_ITANIUM: |
family_str = "Itanium"; |
break; |
case FAMILY_ITANIUM2: |
family_str = "Itanium 2"; |
break; |
default: |
family_str = "Unknown"; |
break; |
} |
printf("cpu%d: %s (%s), archrev=%d, model=%d, revision=%d\n", CPU->id, family_str, vendor, CPU->arch.cpuid3.archrev, CPU->arch.cpuid3.model, CPU->arch.cpuid3.revision); |
} |
/kernel/trunk/arch/ia64/src/context.S |
---|
0,0 → 1,196 |
# |
# 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 context_save_arch |
.global context_restore_arch |
context_save_arch: |
alloc loc0 = ar.pfs, 1, 8, 0, 0 |
mov loc1 = ar.unat ;; |
/* loc2 */ |
mov loc3 = ar.rsc |
.auto |
/* |
* Flush dirty registers to backing store. |
* After this ar.bsp and ar.bspstore are equal. |
*/ |
flushrs |
mov loc4 = ar.bsp |
/* |
* Put RSE to enforced lazy mode. |
* So that ar.rnat can be read. |
*/ |
and loc5 = ~3, loc3 |
mov ar.rsc = loc5 |
mov loc5 = ar.rnat |
.explicit |
mov loc6 = ar.lc |
/* |
* Save application registers |
*/ |
st8 [in0] = loc0, 8 ;; /* save ar.pfs */ |
st8 [in0] = loc1, 8 ;; /* save ar.unat (caller) */ |
mov loc2 = in0 ;; |
add in0 = 8, in0 ;; /* skip ar.unat (callee) */ |
st8 [in0] = loc3, 8 ;; /* save ar.rsc */ |
st8 [in0] = loc4, 8 ;; /* save ar.bsp */ |
st8 [in0] = loc5, 8 ;; /* save ar.rnat */ |
st8 [in0] = loc6, 8 ;; /* save ar.lc */ |
/* |
* Save general registers including NaT bits |
*/ |
st8.spill [in0] = r1, 8 ;; |
st8.spill [in0] = r4, 8 ;; |
st8.spill [in0] = r5, 8 ;; |
st8.spill [in0] = r6, 8 ;; |
st8.spill [in0] = r7, 8 ;; |
st8.spill [in0] = r12, 8 ;; /* save sp */ |
st8.spill [in0] = r13, 8 ;; |
mov loc3 = ar.unat ;; |
st8 [loc2] = loc3 /* save ar.unat (callee) */ |
/* |
* Save branch registers |
*/ |
mov loc2 = b0 ;; |
st8 [in0] = loc2, 8 /* save pc */ |
mov loc3 = b1 ;; |
st8 [in0] = loc3, 8 |
mov loc4 = b2 ;; |
st8 [in0] = loc4, 8 |
mov loc5 = b3 ;; |
st8 [in0] = loc5, 8 |
mov loc6 = b4 ;; |
st8 [in0] = loc6, 8 |
mov loc7 = b5 ;; |
st8 [in0] = loc7, 8 |
/* |
* Save predicate registers |
*/ |
mov loc2 = pr ;; |
st8 [in0] = loc2, 8 |
mov ar.unat = loc1 |
add r8 = r0, r0, 1 /* context_save returns 1 */ |
br.ret.sptk.many b0 |
context_restore_arch: |
alloc loc0 = ar.pfs, 1, 9, 0, 0 ;; |
ld8 loc0 = [in0], 8 ;; /* load ar.pfs */ |
ld8 loc1 = [in0], 8 ;; /* load ar.unat (caller) */ |
ld8 loc2 = [in0], 8 ;; /* load ar.unat (callee) */ |
ld8 loc3 = [in0], 8 ;; /* load ar.rsc */ |
ld8 loc4 = [in0], 8 ;; /* load ar.bsp */ |
ld8 loc5 = [in0], 8 ;; /* load ar.rnat */ |
ld8 loc6 = [in0], 8 ;; /* load ar.lc */ |
.auto |
/* |
* Invalidate the ALAT |
*/ |
invala |
/* |
* Put RSE to enforced lazy mode. |
* So that ar.bspstore and ar.rnat can be written. |
*/ |
movl loc8 = ~3 |
and loc8 = loc3, loc8 |
mov ar.rsc = loc8 |
/* |
* Flush dirty registers to backing store. |
* We do this because we want the following move |
* to ar.bspstore to assign the same value to ar.bsp. |
*/ |
flushrs |
/* |
* Restore application registers |
*/ |
mov ar.bspstore = loc4 /* rse.bspload = ar.bsp = ar.bspstore = loc4 */ |
mov ar.rnat = loc5 |
mov ar.pfs = loc0 |
mov ar.rsc = loc3 |
.explicit |
mov ar.unat = loc2 ;; |
mov ar.lc = loc6 |
/* |
* Restore general registers including NaT bits |
*/ |
ld8.fill r1 = [in0], 8 ;; |
ld8.fill r4 = [in0], 8 ;; |
ld8.fill r5 = [in0], 8 ;; |
ld8.fill r6 = [in0], 8 ;; |
ld8.fill r7 = [in0], 8 ;; |
ld8.fill r12 = [in0], 8 ;; /* restore sp */ |
ld8.fill r13 = [in0], 8 ;; |
/* |
* Restore branch registers |
*/ |
ld8 loc2 = [in0], 8 ;; /* restore pc */ |
mov b0 = loc2 |
ld8 loc3 = [in0], 8 ;; |
mov b1 = loc3 |
ld8 loc4 = [in0], 8 ;; |
mov b2 = loc4 |
ld8 loc5 = [in0], 8 ;; |
mov b3 = loc5 |
ld8 loc6 = [in0], 8 ;; |
mov b4 = loc6 |
ld8 loc7 = [in0], 8 ;; |
mov b5 = loc7 |
/* |
* Restore predicate registers |
*/ |
ld8 loc2 = [in0], 8 ;; |
mov pr = loc2, ~0 |
mov ar.unat = loc1 |
mov r8 = r0 /* context_restore returns 0 */ |
br.ret.sptk.many b0 |
/kernel/trunk/arch/ia64/src/fpu_context.c |
---|
0,0 → 1,40 |
/* |
* Copyright (C) 2005 Jakub Vana |
* 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 <fpu_context.h> |
void fpu_context_save(fpu_context_t *fctx) |
{ |
} |
void fpu_context_restore(fpu_context_t *fctx) |
{ |
} |