Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1212 → Rev 1215

/kernel/trunk/arch/ppc32/include/exception.h
0,0 → 1,78
/*
* 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.
*/
 
#ifndef __ppc32_EXCEPTION_H__
#define __ppc32_EXCEPTION_H__
 
#ifndef __ppc32_TYPES_H__
# include <arch/types.h>
#endif
 
#include <typedefs.h>
 
struct istate {
__u32 r0;
__u32 r2;
__u32 r3;
__u32 r4;
__u32 r5;
__u32 r6;
__u32 r7;
__u32 r8;
__u32 r9;
__u32 r10;
__u32 r11;
__u32 r12;
__u32 r13;
__u32 r14;
__u32 r15;
__u32 r16;
__u32 r17;
__u32 r18;
__u32 r19;
__u32 r20;
__u32 r21;
__u32 r22;
__u32 r23;
__u32 r24;
__u32 r25;
__u32 r26;
__u32 r27;
__u32 r28;
__u32 r29;
__u32 r30;
__u32 r31;
__u32 pc;
__u32 srr1;
__u32 lr;
__u32 cr;
__u32 ctr;
__u32 xer;
};
 
#endif
/kernel/trunk/arch/ppc32/include/types.h
48,6 → 48,12
 
typedef __u32 __native;
 
typedef __u32 pte_t;
/** Page Table Entry. */
typedef struct {
unsigned p : 1; /**< Present bit. */
unsigned a : 1; /**< Accessed bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
} pte_t;
 
#endif
/kernel/trunk/arch/ppc32/include/mm/frame.h
30,7 → 30,7
#define __ppc32_FRAME_H__
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1<<FRAME_WIDTH)
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
/kernel/trunk/arch/ppc32/include/mm/page.h
44,41 → 44,54
# define PA2KA(x) ((x) + 0x80000000)
#endif
 
#define PTL0_ENTRIES_ARCH 0
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 0
/*
* Implementation of generic 4-level page table interface,
* the hardware Page Hash Table is used as cache.
*
* Page table layout:
* - 32-bit virtual addressess
* - Offset is 12 bits => pages are 4K long
* - PTL0 has 1024 entries (10 bits)
* - PTL1 is not used
* - PTL2 is not used
* - PLT3 has 1024 entries (10 bits)
*/
 
#define PTL0_INDEX_ARCH(vaddr) 0
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) 0
#define PTL0_ENTRIES_ARCH 1024
#define PTL1_ENTRIES_ARCH 0
#define PTL2_ENTRIES_ARCH 0
#define PTL3_ENTRIES_ARCH 1024
 
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff)
#define PTL1_INDEX_ARCH(vaddr) 0
#define PTL2_INDEX_ARCH(vaddr) 0
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff)
 
#define SET_PTL0_ADDRESS_ARCH(ptl0)
 
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) ((pte_t *) 0)
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) ((pte_t *) 0)
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) ((pte_t *) 0)
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) ((pte_t *) 0)
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) (((pte_t *) (ptl0))[(i)].pfn << 12)
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) (ptl1)
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) (ptl2)
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) (((pte_t *) (ptl3))[(i)].pfn << 12)
 
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) (((pte_t *) (ptl0))[(i)].pfn = (a) >> 12)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) (((pte_t *) (ptl3))[(i)].pfn = (a) >> 12)
 
#define GET_PTL1_FLAGS_ARCH(ptl0, i) 0
#define GET_PTL2_FLAGS_ARCH(ptl1, i) 0
#define GET_PTL3_FLAGS_ARCH(ptl2, i) 0
#define GET_FRAME_FLAGS_ARCH(ptl3, i) 0
#define GET_PTL1_FLAGS_ARCH(ptl0, i) get_pt_flags((pte_t *) (ptl0), (index_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) get_pt_flags((pte_t *) (ptl3), (index_t) (i))
 
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
 
#define PTE_VALID_ARCH(p) 1
#define PTE_PRESENT_ARCH(p) 1
#define PTE_GET_FRAME_ARCH(p) 0
#define PTE_VALID_ARCH(pte) (*((__u32 *) (pte)) != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0)
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12)
 
#ifndef __ASM__
 
86,6 → 99,28
#include <arch/mm/frame.h>
#include <arch/types.h>
 
static inline int get_pt_flags(pte_t *pt, index_t i)
{
pte_t *p = &pt[i];
return (
(1 << PAGE_CACHEABLE_SHIFT) |
((!p->p) << PAGE_PRESENT_SHIFT) |
(1 << PAGE_USER_SHIFT) |
(1 << PAGE_READ_SHIFT) |
(1 << PAGE_WRITE_SHIFT) |
(1 << PAGE_EXEC_SHIFT)
);
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
{
pte_t *p = &pt[i];
p->p = !(flags & PAGE_NOT_PRESENT);
p->valid = 1;
}
 
extern void page_arch_init(void);
 
#endif /* __ASM__ */
/kernel/trunk/arch/ppc32/include/mm/asid.h
26,13 → 26,19
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __ppc32_ASID_H__
#define __ppc32_ASID_H__
/*
* ia32 has no hardware support for address space identifiers.
* This file is provided to do nop-implementation of mm/asid.h
* interface.
*/
 
#ifndef __ia32_ASID_H__
#define __ia32_ASID_H__
 
typedef int asid_t;
 
#define ASID_MAX_ARCH 3
#define ASID_MAX_ARCH 3
 
#define asid_get() (ASID_START+1)
#define asid_get() (ASID_START+1)
 
#endif
/kernel/trunk/arch/ppc32/include/mm/tlb.h
1,5 → 1,5
/*
* Copyright (C) 2005 Jakub Jermar
* Copyright (C) 2006 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
29,7 → 29,9
#ifndef __ppc32_TLB_H__
#define __ppc32_TLB_H__
 
#define tlb_arch_init()
#define tlb_print()
#include <arch/exception.h>
#include <typedefs.h>
 
extern void pht_refill(istate_t *istate);
 
#endif
/kernel/trunk/arch/ppc32/Makefile.inc
30,7 → 30,7
#
 
BFD_NAME = elf32-powerpc
BFD_ARCH = powerpc
BFD_ARCH = powerpc:common
BFD = binary
TARGET = ppc-linux-gnu
TOOLCHAIN_DIR = /usr/local/ppc/bin
78,4 → 78,5
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/memory_init.c \
arch/$(ARCH)/src/mm/page.c
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c
/kernel/trunk/arch/ppc32/src/exception.S
31,59 → 31,7
 
.section K_UNMAPPED_TEXT_START, "ax"
 
.org 0x100
.global exc_system_reset
exc_system_reset:
b exc_system_reset
 
.org 0x200
.global exc_machine_check
exc_machine_check:
b exc_machine_check
 
.org 0x300
.global exc_data_storage
exc_data_storage:
b exc_data_storage
 
.org 0x380
.global exc_data_segment
exc_data_segment:
b exc_data_segment
 
.org 0x400
.global exc_instruction_storage
exc_instruction_storage:
b exc_instruction_storage
 
.org 0x480
.global exc_instruction_segment
exc_instruction_segment:
b exc_instruction_segment
 
.org 0x500
.global exc_external
exc_external:
b exc_external
 
.org 0x600
.global exc_alignment
exc_alignment:
b exc_alignment
 
.org 0x700
.global exc_program
exc_program:
b exc_program
 
.org 0x800
.global exc_fp_unavailable
exc_fp_unavailable:
b exc_fp_unavailable
 
.org 0x900
.global exc_decrementer
exc_decrementer:
.macro CONTEXT_STORE
mtspr sprg1, sp
subis sp, sp, 0x8000
138,7 → 86,73
mfxer r3
stw r3, 144(sp)
.endm
 
.org 0x100
.global exc_system_reset
exc_system_reset:
b exc_system_reset
 
.org 0x200
.global exc_machine_check
exc_machine_check:
b exc_machine_check
 
.org 0x300
.global exc_data_storage
exc_data_storage:
CONTEXT_STORE
 
lis r3, pht_refill@ha
addi r3, r3, pht_refill@l
mtspr srr0, r3
mfmsr r3
ori r3, r3, (msr_ir | msr_dr)@l
mtspr srr1, r3
lis r3, iret@ha
addi r3, r3, iret@l
mtlr r3
addis sp, sp, 0x8000
rfi
 
.org 0x400
.global exc_instruction_storage
exc_instruction_storage:
b exc_instruction_storage
 
.org 0x480
.global exc_instruction_segment
exc_instruction_segment:
b exc_instruction_segment
 
.org 0x500
.global exc_external
exc_external:
b exc_external
 
.org 0x600
.global exc_alignment
exc_alignment:
b exc_alignment
 
.org 0x700
.global exc_program
exc_program:
b exc_program
 
.org 0x800
.global exc_fp_unavailable
exc_fp_unavailable:
b exc_fp_unavailable
 
.org 0x900
.global exc_decrementer
exc_decrementer:
CONTEXT_STORE
 
lis r3, exc_dispatch@ha
addi r3, r3, exc_dispatch@l
mtspr srr0, r3
/kernel/trunk/arch/ppc32/src/mm/tlb.c
0,0 → 1,155
/*
* 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.
*/
 
#include <arch/mm/tlb.h>
#include <arch/types.h>
#include <mm/tlb.h>
#include <mm/page.h>
#include <mm/as.h>
#include <arch.h>
#include <print.h>
#include <symtab.h>
 
 
/** Initialize Page Hash Table.
*
* Setup the Page Hash Table with no entries.
*
*/
void tlb_arch_init(void)
{
}
 
 
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
* The AS->lock must be held on entry to this function.
*
* @param badvaddr Faulting virtual address.
* @return PTE on success, NULL otherwise.
*
*/
static pte_t *find_mapping_and_check(__address badvaddr)
{
/*
* Check if the mapping exists in page tables.
*/
pte_t *pte = page_mapping_find(AS, badvaddr);
if ((pte) && (pte->p)) {
/*
* Mapping found in page tables.
* Immediately succeed.
*/
return pte;
} else {
/*
* Mapping not found in page tables.
* Resort to higher-level page fault handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(badvaddr)) {
/*
* The higher-level page fault handler succeeded,
* The mapping ought to be in place.
*/
page_table_lock(AS, true);
pte = page_mapping_find(AS, badvaddr);
ASSERT((pte) && (pte->p));
return pte;
} else {
page_table_lock(AS, true);
printf("Page fault.\n");
return NULL;
}
}
}
 
 
static void pht_refill_fail(__address badvaddr, istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
 
char *s = get_symtab_entry(istate->pc);
if (s)
symbol = s;
s = get_symtab_entry(istate->lr);
if (s)
sym2 = s;
panic("%X: PHT Refill Exception at %X(%s<-%s)\n", badvaddr, istate->pc, symbol, sym2);
}
 
 
/** Process Data Storage Interrupt
*
* @param istate Interrupted register context.
*
*/
void pht_refill(istate_t *istate)
{
asid_t asid;
__address badvaddr;
pte_t *pte;
__asm__ volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
spinlock_lock(&AS->lock);
asid = AS->asid;
spinlock_unlock(&AS->lock);
page_table_lock(AS, true);
pte = find_mapping_and_check(badvaddr);
if (!pte)
goto fail;
 
/*
* Record access to PTE.
*/
pte->a = 1;
// FIXME: Insert entry into PHT
 
page_table_unlock(AS, true);
return;
fail:
page_table_unlock(AS, true);
pht_refill_fail(badvaddr, istate);
}
 
 
/** Print contents of Page Hash Table. */
void tlb_print(void)
{
}
/kernel/trunk/arch/ppc64/Makefile.inc
30,10 → 30,10
#
 
BFD_NAME = elf64-powerpc
BFD_ARCH = powerpc
BFD_ARCH = powerpc:common64
BFD = binary
TARGET = ppc-linux-gnu
TOOLCHAIN_DIR = /usr/local/ppc/bin
TARGET = ppc64-linux-gnu
TOOLCHAIN_DIR = /usr/local/ppc64/bin
 
## Make some default assumptions
#