Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3675 → Rev 4377

/branches/tracing/kernel/arch/ppc32/_link.ld.in
1,11 → 1,11
/** PPC32 linker script
*
* umapped section:
* kernel text
* kernel data
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
* kernel text
* kernel data
*
*/
 
27,7 → 27,7
unmapped_kdata_start = .;
}
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) {
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) {
ktext_start = .;
*(K_TEXT_START);
*(.text);
37,22 → 37,22
*(K_DATA_START);
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
LONG(PA2KA(BOOT_OFFSET));
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
*(symtab.*); /* Symbol table, must be LAST symbol!*/
kdata_end = .;
}
}
/branches/tracing/kernel/arch/ppc32/include/asm/regname.h
211,6 → 211,9
#define dbat2l 541
#define dbat3u 542
#define dbat3l 543
#define tlbmiss 980
#define ptehi 981
#define ptelo 982
#define hid0 1008
 
/* MSR bits */
220,6 → 223,7
#define msr_ee (1 << 15)
 
/* HID0 bits */
#define hid0_sten (1 << 24)
#define hid0_ice (1 << 15)
#define hid0_dce (1 << 14)
#define hid0_icfi (1 << 11)
/branches/tracing/kernel/arch/ppc32/include/exception.h
75,6 → 75,7
uint32_t lr;
uint32_t ctr;
uint32_t xer;
uint32_t dar;
uint32_t r12;
uint32_t sp;
} istate_t;
/branches/tracing/kernel/arch/ppc32/include/types.h
57,6 → 57,9
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct {
} fncptr_t;
 
/**< Formats for uintptr_t, size_t, count_t and index_t */
#define PRIp "x"
#define PRIs "u"
84,11 → 87,13
 
/** Page Table Entry. */
typedef struct {
unsigned p : 1; /**< Present bit. */
unsigned a : 1; /**< Accessed bit. */
unsigned g : 1; /**< Global bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
unsigned present : 1; /**< Present bit. */
unsigned page_write_through : 1; /**< Write thought caching. */
unsigned page_cache_disable : 1; /**< No caching. */
unsigned accessed : 1; /**< Accessed bit. */
unsigned global : 1; /**< Global bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
} pte_t;
 
#endif
/branches/tracing/kernel/arch/ppc32/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
35,7 → 35,7
#ifndef KERN_ppc32_ARCH_H_
#define KERN_ppc32_ARCH_H_
 
#include <arch/drivers/cuda.h>
extern void arch_pre_main(void);
 
#endif
 
/branches/tracing/kernel/arch/ppc32/include/boot/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
35,21 → 35,24
#ifndef KERN_ppc32_BOOT_H_
#define KERN_ppc32_BOOT_H_
 
#define BOOT_OFFSET 0x8000
#define BOOT_OFFSET 0x8000
 
/* Temporary stack size for boot process */
#define TEMP_STACK_SIZE 0x1000
#define TEMP_STACK_SIZE 0x1000
 
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
#ifndef __ASM__
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
#include <arch/types.h>
 
typedef struct {
uintptr_t addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
79,13 → 82,13
typedef struct {
uintptr_t addr;
unsigned int size;
} keyboard_t;
} macio_t;
 
typedef struct {
memmap_t memmap;
taskmap_t taskmap;
screen_t screen;
keyboard_t keyboard;
macio_t macio;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
/branches/tracing/kernel/arch/ppc32/include/asm.h
36,6 → 36,7
#define KERN_ppc32_ASM_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
 
/** Enable interrupts.
149,6 → 150,36
 
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
#endif
 
/** @}
/branches/tracing/kernel/arch/ppc32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
35,13 → 35,13
#ifndef KERN_ppc32_FRAME_H_
#define KERN_ppc32_FRAME_H_
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
/branches/tracing/kernel/arch/ppc32/include/mm/page.h
120,7 → 120,7
 
/* Macros for querying the last-level PTEs. */
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->present != 0)
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12)
#define PTE_WRITABLE_ARCH(pte) 1
#define PTE_EXECUTABLE_ARCH(pte) 1
134,13 → 134,13
{
pte_t *p = &pt[i];
return ((1 << PAGE_CACHEABLE_SHIFT) |
((!p->p) << PAGE_PRESENT_SHIFT) |
return (((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT) |
((!p->present) << PAGE_PRESENT_SHIFT) |
(1 << PAGE_USER_SHIFT) |
(1 << PAGE_READ_SHIFT) |
(1 << PAGE_WRITE_SHIFT) |
(1 << PAGE_EXEC_SHIFT) |
(p->g << PAGE_GLOBAL_SHIFT));
(p->global << PAGE_GLOBAL_SHIFT));
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
147,8 → 147,9
{
pte_t *p = &pt[i];
p->p = !(flags & PAGE_NOT_PRESENT);
p->g = (flags & PAGE_GLOBAL) != 0;
p->page_cache_disable = !(flags & PAGE_CACHEABLE);
p->present = !(flags & PAGE_NOT_PRESENT);
p->global = (flags & PAGE_GLOBAL) != 0;
p->valid = 1;
}
 
/branches/tracing/kernel/arch/ppc32/include/mm/tlb.h
39,6 → 39,11
#include <arch/types.h>
#include <typedefs.h>
 
#define WIMG_GUARDED 0x01
#define WIMG_COHERENT 0x02
#define WIMG_NO_CACHE 0x04
#define WIMG_WRITETHRU 0x08
 
typedef struct {
unsigned v : 1; /**< Valid */
unsigned vsid : 24; /**< Virtual Segment ID */
53,9 → 58,27
unsigned pp : 2; /**< Page protection */
} phte_t;
 
typedef struct {
unsigned v : 1;
unsigned vsid : 24;
unsigned reserved0 : 1;
unsigned api : 6;
} ptehi_t;
 
typedef struct {
unsigned rpn : 20;
unsigned xpn : 3;
unsigned reserved0 : 1;
unsigned c : 1;
unsigned wimg : 4;
unsigned x : 1;
unsigned pp : 2;
} ptelo_t;
 
extern void pht_init(void);
extern void pht_refill(int n, istate_t *istate);
extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
extern void pht_init(void);
extern bool pht_refill_real(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
extern void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
 
#endif
 
/branches/tracing/kernel/arch/ppc32/include/barrier.h
55,6 → 55,7
"dcbst 0, %0\n"
"sync\n"
"icbi 0, %0\n"
"sync\n"
"isync\n"
:: "r" (addr)
);
76,7 → 77,10
asm volatile ("icbi 0, %0\n" :: "r" (addr + i));
}
 
asm volatile ("isync");
asm volatile (
"sync\n"
"isync\n"
);
}
 
#endif
/branches/tracing/kernel/arch/ppc32/include/drivers/cuda.h
File deleted
/branches/tracing/kernel/arch/ppc32/include/drivers/pic.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
36,6 → 36,7
#define KERN_ppc32_PIC_H_
 
#include <arch/types.h>
#include <ddi/irq.h>
 
#define PIC_PENDING_LOW 8
#define PIC_PENDING_HIGH 4
44,11 → 45,11
#define PIC_ACK_LOW 10
#define PIC_ACK_HIGH 6
 
void pic_init(uintptr_t base, size_t size);
void pic_enable_interrupt(int intnum);
void pic_disable_interrupt(int intnum);
void pic_ack_interrupt(int intnum);
int pic_get_pending(void);
extern void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg);
extern void pic_enable_interrupt(inr_t intnum);
extern void pic_disable_interrupt(inr_t intnum);
extern void pic_ack_interrupt(void *arg, inr_t intnum);
extern int pic_get_pending(void);
 
#endif
 
/branches/tracing/kernel/arch/ppc32/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf32-powerpc
BFD_ARCH = powerpc:common
BFD = binary
45,44 → 41,21
 
DEFS += -D__32_BITS__
 
## Own configuration directives
#
 
CONFIG_FB = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/debug/panic.s \
arch/$(ARCH)/src/fpu_context.S \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/ppc32.c \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/exception.S \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/cuda.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/drivers/pic.c
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/debug/panic.s \
arch/$(KARCH)/src/fpu_context.S \
arch/$(KARCH)/src/boot/boot.S \
arch/$(KARCH)/src/ppc32.c \
arch/$(KARCH)/src/dummy.s \
arch/$(KARCH)/src/exception.S \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/drivers/pic.c
/branches/tracing/kernel/arch/ppc32/src/exception.S
60,7 → 60,7
2:
subi sp, sp, 160
subi sp, sp, 164
stw r0, 8(sp)
stw r2, 12(sp)
stw r3, 16(sp)
109,11 → 109,14
mfxer r12
stw r12, 148(sp)
mfsprg1 r12
mfdar r12
stw r12, 152(sp)
mfsprg1 r12
stw r12, 156(sp)
mfsprg2 r12
stw r12, 156(sp)
stw r12, 160(sp)
.endm
 
.org 0x100
137,16 → 140,7
exc_data_storage:
CONTEXT_STORE
li r3, 2
mr r4, sp
addi r4, r4, 8
bl pht_real_refill
cmpwi r3, 0
bne iret_real
li r3, 2
b jump_to_kernel
b data_storage
 
.org 0x400
.global exc_instruction_storage
153,17 → 147,8
exc_instruction_storage:
CONTEXT_STORE
li r3, 3
mr r4, sp
addi r4, r4, 8
bl pht_real_refill
cmpwi r3, 0
bne iret_real
b instruction_storage
 
li r3, 3
b jump_to_kernel
 
.org 0x500
.global exc_external
exc_external:
223,7 → 208,7
.org 0xc00
.global exc_syscall
exc_syscall:
CONTEXT_STORE
CONTEXT_STORE
b jump_to_kernel_syscall
 
235,7 → 220,63
li r3, 12
b jump_to_kernel
 
.org 0x1000
.global exc_itlb_miss
exc_itlb_miss:
CONTEXT_STORE
b tlb_miss
 
.org 0x1100
.global exc_dtlb_miss_load
exc_dtlb_miss_load:
CONTEXT_STORE
b tlb_miss
 
.org 0x1200
.global exc_dtlb_miss_store
exc_dtlb_miss_store:
CONTEXT_STORE
b tlb_miss
 
.org 0x4000
data_storage:
li r3, 2
mr r4, sp
addi r4, r4, 8
bl pht_refill_real
cmpwi r3, 0
bne iret_real
li r3, 2
b jump_to_kernel
 
instruction_storage:
li r3, 3
mr r4, sp
addi r4, r4, 8
bl pht_refill_real
cmpwi r3, 0
bne iret_real
li r3, 3
b jump_to_kernel
 
tlb_miss:
li r3, 16
mfspr r4, tlbmiss
mfspr r5, ptehi
mfspr r6, ptelo
mr r7, sp
addi r7, r7, 20
bl tlb_refill_real
b iret_real
 
jump_to_kernel:
lis r12, iret@ha
addi r12, r12, iret@l
272,7 → 313,6
rfi
 
iret_real:
lwz r0, 8(sp)
lwz r2, 12(sp)
lwz r3, 16(sp)
322,7 → 362,7
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
rfi
/branches/tracing/kernel/arch/ppc32/src/asm.S
34,6 → 34,7
.global iret
.global iret_syscall
.global memsetb
.global memsetw
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
131,8 → 132,8
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
rfi
 
197,14 → 198,17
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
 
rfi
 
memsetb:
b _memsetb
 
memsetw:
b _memsetw
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
/branches/tracing/kernel/arch/ppc32/src/boot/boot.S
33,7 → 33,7
 
.global kernel_image_start
kernel_image_start:
 
# load temporal kernel stack
lis sp, kernel_stack@ha
52,7 → 52,7
beq bootinfo_end
addis r3, r3, 0x8000
 
lis r31, bootinfo@ha
addi r31, r31, bootinfo@l # r31 = bootinfo
/branches/tracing/kernel/arch/ppc32/src/ppc32.c
35,7 → 35,7
#include <config.h>
#include <arch.h>
#include <arch/boot/boot.h>
#include <arch/drivers/cuda.h>
#include <genarch/drivers/via-cuda/cuda.h>
#include <arch/interrupt.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
42,24 → 42,29
#include <userspace.h>
#include <proc/uarg.h>
#include <console/console.h>
#include <ddi/device.h>
#include <ddi/irq.h>
#include <arch/drivers/pic.h>
#include <align.h>
#include <macros.h>
#include <string.h>
 
#define IRQ_COUNT 64
#define IRQ_COUNT 64
#define IRQ_CUDA 10
 
bootinfo_t bootinfo;
 
/** Performs ppc32-specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Setup usermode */
init.cnt = bootinfo.taskmap.count;
uint32_t i;
for (i = 0; i < bootinfo.taskmap.count; i++) {
for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) {
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr);
init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo.taskmap.tasks[i].name);
}
}
 
75,44 → 80,67
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
 
#ifdef CONFIG_FB
/* Initialize framebuffer */
unsigned int visual;
switch (bootinfo.screen.bpp) {
case 8:
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_5_5;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
break;
default:
panic("Unsupported bits per pixel");
if (bootinfo.screen.addr) {
unsigned int visual;
switch (bootinfo.screen.bpp) {
case 8:
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_5_5;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
break;
default:
panic("Unsupported bits per pixel.");
}
fb_properties_t prop = {
.addr = bootinfo.screen.addr,
.offset = 0,
.x = bootinfo.screen.width,
.y = bootinfo.screen.height,
.scan = bootinfo.screen.scanline,
.visual = visual,
};
fb_init(&prop);
}
fb_properties_t prop = {
.addr = bootinfo.screen.addr,
.offset = 0,
.x = bootinfo.screen.width,
.y = bootinfo.screen.height,
.scan = bootinfo.screen.scanline,
.visual = visual,
};
fb_init(&prop);
#endif
/* Initialize IRQ routing */
irq_init(IRQ_COUNT, IRQ_COUNT);
/* Initialize PIC */
pic_init(bootinfo.keyboard.addr, PAGE_SIZE);
/* Initialize I/O controller */
cuda_init(device_assign_devno(),
bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE);
if (bootinfo.macio.addr) {
/* Initialize PIC */
cir_t cir;
void *cir_arg;
pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg);
#ifdef CONFIG_VIA_CUDA
uintptr_t pa = bootinfo.macio.addr + 0x16000;
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
size_t size = 2 * PAGE_SIZE;
cuda_t *cuda = (cuda_t *)
(hw_map(aligned_addr, offset + size) + offset);
/* Initialize I/O controller */
cuda_instance_t *cuda_instance =
cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
if (cuda_instance) {
indev_t *sink = stdin_wire();
cuda_wire(cuda_instance, sink);
}
#endif
}
/* Merge all zones to 1 big zone */
zone_merge_all();
143,8 → 171,7
(uintptr_t) kernel_uarg->uspace_entry);
/* Unreachable */
for (;;)
;
while (true);
}
 
/** Acquire console back for kernel
152,7 → 179,9
*/
void arch_grab_console(void)
{
cuda_grab();
#ifdef CONFIG_FB
fb_redraw();
#endif
}
 
/** Return console to userspace
160,8 → 189,27
*/
void arch_release_console(void)
{
cuda_release();
}
 
/** Construct function pointer
*
* @param fptr function pointer structure
* @param addr function address
* @param caller calling function address
*
* @return address of the function pointer
*
*/
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller)
{
return addr;
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/tracing/kernel/arch/ppc32/src/mm/tlb.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
39,9 → 39,18
#include <mm/as.h>
#include <arch.h>
#include <print.h>
#include <macros.h>
#include <symtab.h>
 
static unsigned int seed = 10;
static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
 
 
#define TLB_FLUSH \
"tlbie %0\n" \
"addi %0, %0, 0x1000\n"
 
 
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
66,7 → 75,7
* Check if the mapping exists in page tables.
*/
pte_t *pte = page_mapping_find(as, badvaddr);
if ((pte) && (pte->p)) {
if ((pte) && (pte->present)) {
/*
* Mapping found in page tables.
* Immediately succeed.
88,7 → 97,7
*/
page_table_lock(as, lock);
pte = page_mapping_find(as, badvaddr);
ASSERT((pte) && (pte->p));
ASSERT((pte) && (pte->present));
*pfrc = 0;
return pte;
case AS_PF_DEFER:
100,7 → 109,7
*pfrc = rc;
return NULL;
default:
panic("unexpected rc (%d)\n", rc);
panic("Unexpected rc (%d).", rc);
}
}
}
108,25 → 117,20
 
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
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;
symbol = symtab_fmt_name_lookup(istate->pc);
sym2 = symtab_fmt_name_lookup(istate->lr);
 
fault_if_from_uspace(istate,
"%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr,
"PHT Refill Exception on %p.", badvaddr);
panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr,
istate->pc, symbol, sym2);
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr,
istate->pc, symbol, sym2);
}
 
 
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn)
static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
152,11 → 156,12
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) &&
(phte[base + i].api == api))) {
if ((phte[base + i].v)
&& (phte[base + i].vsid == vsid)
&& (phte[base + i].api == api)
&& (phte[base + i].h == 0)) {
found = true;
break;
}
163,86 → 168,25
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base2 + i].v) ||
((phte[base2 + i].vsid == vsid) &&
(phte[base2 + i].api == api))) {
if (!phte[base + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
}
}
phte[base + i].v = 1;
phte[base + i].vsid = vsid;
phte[base + i].h = h;
phte[base + i].api = api;
phte[base + i].rpn = pfn;
phte[base + i].r = 0;
phte[base + i].c = 0;
phte[base + i].pp = 2; // FIXME
}
 
 
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (vaddr)
);
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte_physical[base + i].v) ||
((phte_physical[base + i].vsid == vsid) &&
(phte_physical[base + i].api == api))) {
found = true;
break;
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte_physical[base2 + i].v) ||
((phte_physical[base2 + i].vsid == vsid) &&
(phte_physical[base2 + i].api == api))) {
if ((phte[base2 + i].v)
&& (phte[base2 + i].vsid == vsid)
&& (phte[base2 + i].api == api)
&& (phte[base2 + i].h == 1)) {
found = true;
base = base2;
h = 1;
251,26 → 195,37
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte[base2 + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
}
if (!found)
i = RANDI(seed) % 8;
}
phte_physical[base + i].v = 1;
phte_physical[base + i].vsid = vsid;
phte_physical[base + i].h = h;
phte_physical[base + i].api = api;
phte_physical[base + i].rpn = pfn;
phte_physical[base + i].r = 0;
phte_physical[base + i].c = 0;
phte_physical[base + i].pp = 2; // FIXME
phte[base + i].v = 1;
phte[base + i].vsid = vsid;
phte[base + i].h = h;
phte[base + i].api = api;
phte[base + i].rpn = pte->pfn;
phte[base + i].r = 0;
phte[base + i].c = 0;
phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0);
phte[base + i].pp = 2; // FIXME
}
 
 
/** Process Instruction/Data Storage Interrupt
/** Process Instruction/Data Storage Exception
*
* @param n Interrupt vector number.
* @param istate Interrupted register context.
* @param n Exception vector number.
* @param istate Interrupted register context.
*
*/
void pht_refill(int n, istate_t *istate)
289,12 → 244,9
lock = true;
}
if (n == VECTOR_DATA_STORAGE) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
if (n == VECTOR_DATA_STORAGE)
badvaddr = istate->dar;
else
badvaddr = istate->pc;
page_table_lock(as, lock);
314,12 → 266,12
page_table_unlock(as, lock);
return;
default:
panic("Unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
pte->a = 1; /* Record access to PTE */
pht_insert(badvaddr, pte->pfn);
pte->accessed = 1; /* Record access to PTE */
pht_insert(badvaddr, pte);
page_table_unlock(as, lock);
return;
330,22 → 282,19
}
 
 
/** Process Instruction/Data Storage Interrupt in Real Mode
/** Process Instruction/Data Storage Exception in Real Mode
*
* @param n Interrupt vector number.
* @param istate Interrupted register context.
* @param n Exception vector number.
* @param istate Interrupted register context.
*
*/
bool pht_real_refill(int n, istate_t *istate)
bool pht_refill_real(int n, istate_t *istate)
{
uintptr_t badvaddr;
if (n == VECTOR_DATA_STORAGE) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
if (n == VECTOR_DATA_STORAGE)
badvaddr = istate->dar;
else
badvaddr = istate->pc;
uint32_t physmem;
354,15 → 303,140
: "=r" (physmem)
);
if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) {
pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);
return true;
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
return false;
uint32_t page = (badvaddr >> 12) & 0xffff;
uint32_t api = (badvaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (badvaddr)
);
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((phte_real[base + i].v)
&& (phte_real[base + i].vsid == vsid)
&& (phte_real[base + i].api == api)
&& (phte_real[base + i].h == 0)) {
found = true;
break;
}
}
return false;
if (!found) {
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte_real[base + i].v) {
found = true;
break;
}
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((phte_real[base2 + i].v)
&& (phte_real[base2 + i].vsid == vsid)
&& (phte_real[base2 + i].api == api)
&& (phte_real[base2 + i].h == 1)) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte_real[base2 + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
}
if (!found) {
/* Use secondary hash to avoid collisions
with usual PHT refill handler. */
i = RANDI(seed_real) % 8;
base = base2;
h = 1;
}
}
phte_real[base + i].v = 1;
phte_real[base + i].vsid = vsid;
phte_real[base + i].h = h;
phte_real[base + i].api = api;
phte_real[base + i].rpn = KA2PA(badvaddr) >> 12;
phte_real[base + i].r = 0;
phte_real[base + i].c = 0;
phte_real[base + i].wimg = 0;
phte_real[base + i].pp = 2; // FIXME
return true;
}
 
 
/** Process ITLB/DTLB Miss Exception in Real Mode
*
*
*/
void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate)
{
uint32_t badvaddr = tlbmiss & 0xfffffffc;
uint32_t physmem;
asm volatile (
"mfsprg3 %0\n"
: "=r" (physmem)
);
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
return; // FIXME
ptelo.rpn = KA2PA(badvaddr) >> 12;
ptelo.wimg = 0;
ptelo.pp = 2; // FIXME
uint32_t index = 0;
asm volatile (
"mtspr 981, %0\n"
"mtspr 982, %1\n"
"tlbld %2\n"
"tlbli %2\n"
: "=r" (index)
: "r" (ptehi),
"r" (ptelo)
);
}
 
 
void tlb_arch_init(void)
{
tlb_invalidate_all();
371,9 → 445,87
 
void tlb_invalidate_all(void)
{
uint32_t index;
asm volatile (
"tlbia\n"
"li %0, 0\n"
"sync\n"
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
"eieio\n"
"tlbsync\n"
"sync\n"
: "=r" (index)
);
}
 
442,7 → 594,7
: "=r" (vsid)
: "r" (sr << 28)
);
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr,
printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
((vsid >> 30) & 1) ? " supervisor" : "",
((vsid >> 29) & 1) ? " user" : "");
/branches/tracing/kernel/arch/ppc32/src/mm/frame.c
74,7 → 74,7
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE))
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE);
}
 
/* First is exception vector, second is 'implementation specific',
third and fourth is reserved, other contain real mode code */
frame_mark_unavailable(0, 8);
/branches/tracing/kernel/arch/ppc32/src/mm/page.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
49,7 → 49,7
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) >
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%" PRIs " bytes)",
panic("Unable to map physical memory %p (%" PRIs " bytes).",
physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
/branches/tracing/kernel/arch/ppc32/src/dummy.s
30,6 → 30,7
 
.global asm_delay_loop
.global sys_tls_set
.global cpu_halt
 
sys_tls_set:
b sys_tls_set
36,3 → 37,6
 
asm_delay_loop:
blr
 
cpu_halt:
b cpu_halt
/branches/tracing/kernel/arch/ppc32/src/interrupt.c
60,7 → 60,6
int inum;
while ((inum = pic_get_pending()) != -1) {
bool ack = false;
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
69,11 → 68,17
if (irq->preack) {
/* Acknowledge the interrupt before processing */
pic_ack_interrupt(inum);
ack = true;
if (irq->cir)
irq->cir(irq->cir_arg, irq->inr);
}
irq->handler(irq, irq->arg);
irq->handler(irq);
if (!irq->preack) {
if (irq->cir)
irq->cir(irq->cir_arg, irq->inr);
}
spinlock_unlock(&irq->lock);
} else {
/*
83,9 → 88,6
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
if (!ack)
pic_ack_interrupt(inum);
}
}
 
92,8 → 94,8
 
static void exception_decrementer(int n, istate_t *istate)
{
start_decrementer();
clock();
start_decrementer();
}
 
#ifdef CONFIG_UDEBUG
/branches/tracing/kernel/arch/ppc32/src/drivers/cuda.c
File deleted
/branches/tracing/kernel/arch/ppc32/src/drivers/pic.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
38,53 → 38,61
#include <byteorder.h>
#include <bitops.h>
 
static volatile uint32_t *pic;
static volatile uint32_t *pic = NULL;
 
void pic_init(uintptr_t base, size_t size)
void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg)
{
pic = (uint32_t *) hw_map(base, size);
*cir = pic_ack_interrupt;
*cir_arg = NULL;
}
 
void pic_enable_interrupt(int intnum)
void pic_enable_interrupt(inr_t intnum)
{
if (intnum < 32) {
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum);
} else {
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32));
if (pic) {
if (intnum < 32)
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum);
else
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32));
}
}
 
void pic_disable_interrupt(int intnum)
void pic_disable_interrupt(inr_t intnum)
{
if (intnum < 32) {
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum));
} else {
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32)));
if (pic) {
if (intnum < 32)
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum));
else
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32)));
}
}
 
void pic_ack_interrupt(int intnum)
void pic_ack_interrupt(void *arg, inr_t intnum)
{
if (intnum < 32)
pic[PIC_ACK_LOW] = 1 << intnum;
else
pic[PIC_ACK_HIGH] = 1 << (intnum - 32);
if (pic) {
if (intnum < 32)
pic[PIC_ACK_LOW] = 1 << intnum;
else
pic[PIC_ACK_HIGH] = 1 << (intnum - 32);
}
}
 
/** Return number of pending interrupt */
int pic_get_pending(void)
{
int pending;
 
pending = pic[PIC_PENDING_LOW];
if (pending)
return fnzb32(pending);
if (pic) {
int pending;
pending = pic[PIC_PENDING_LOW];
if (pending)
return fnzb32(pending);
pending = pic[PIC_PENDING_HIGH];
if (pending)
return fnzb32(pending) + 32;
}
pending = pic[PIC_PENDING_HIGH];
if (pending)
return fnzb32(pending) + 32;
return -1;
}