/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; |
} |