/branches/dynload/kernel/arch/mips32/include/mm/page.h |
---|
40,8 → 40,6 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
/branches/dynload/kernel/arch/mips32/include/mm/tlb.h |
---|
35,6 → 35,9 |
#ifndef KERN_mips32_TLB_H_ |
#define KERN_mips32_TLB_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/mm/asid.h> |
#include <arch/exception.h> |
#ifdef TLBCNT |
46,7 → 49,13 |
#define TLB_WIRED 1 |
#define TLB_KSTACK_WIRED_INDEX 0 |
#define TLB_PAGE_MASK_16K (0x3<<13) |
#define TLB_PAGE_MASK_4K (0x000 << 13) |
#define TLB_PAGE_MASK_16K (0x003 << 13) |
#define TLB_PAGE_MASK_64K (0x00f << 13) |
#define TLB_PAGE_MASK_256K (0x03f << 13) |
#define TLB_PAGE_MASK_1M (0x0ff << 13) |
#define TLB_PAGE_MASK_4M (0x3ff << 13) |
#define TLB_PAGE_MASK_16M (0xfff << 13) |
#define PAGE_UNCACHED 2 |
#define PAGE_CACHEABLE_EXC_WRITE 5 |
159,6 → 168,8 |
extern void tlb_invalid(istate_t *istate); |
extern void tlb_refill(istate_t *istate); |
extern void tlb_modified(istate_t *istate); |
extern void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
extern void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
#endif |
/branches/dynload/kernel/arch/mips32/include/mm/as.h |
---|
38,7 → 38,7 |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x80000000 |
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffff |
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0x9fffffff |
#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x00000000 |
#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x7fffffff |
/branches/dynload/kernel/arch/mips32/include/drivers/arc.h |
---|
File deleted |
/branches/dynload/kernel/arch/mips32/include/drivers/serial.h |
---|
37,6 → 37,8 |
#include <console/chardev.h> |
#define SERIAL_ADDRESS 0x98000000 |
#define SERIAL_MAX 4 |
#define SERIAL_COM1 0x3f8 |
#define SERIAL_COM1_IRQ 4 |
43,16 → 45,19 |
#define SERIAL_COM2 0x2f8 |
#define SERIAL_COM2_IRQ 3 |
#define P_WRITEB(where,what) (*((volatile char *) (0xB8000000+where))=what) |
#define P_READB(where) (*((volatile char *)(0xB8000000+where))) |
#define P_WRITEB(where, what) (*((volatile char *) (SERIAL_ADDRESS + where)) = what) |
#define P_READB(where) (*((volatile char *) (SERIAL_ADDRESS + where))) |
#define SERIAL_READ(x) P_READB(x) |
#define SERIAL_WRITE(x,c) P_WRITEB(x,c) |
/* Interrupt enable register */ |
#define SERIAL_READ_IER(x) (P_READB((x) + 1)) |
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x)+1,c)) |
/* Interrupt identification register */ |
#define SERIAL_READ_IIR(x) (P_READB((x) + 2)) |
/* Line status register */ |
#define SERIAL_READ_LSR(x) (P_READB((x) + 5)) |
#define TRANSMIT_EMPTY_BIT 5 |
/branches/dynload/kernel/arch/mips32/include/drivers/msim.h |
---|
35,6 → 35,11 |
#ifndef KERN_mips32_MSIM_H_ |
#define KERN_mips32_MSIM_H_ |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0x90000000 |
#define MSIM_KBD_ADDRESS 0x90000000 |
#define MSIM_KBD_IRQ 2 |
#include <console/chardev.h> |
void msim_console(devno_t devno); |
/branches/dynload/kernel/arch/mips32/Makefile.inc |
---|
29,17 → 29,19 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_ARCH = mips |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = /usr/local/mipsel |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel |
KERNEL_LOAD_ADDRESS = 0x80100000 |
INIT_ADDRESS = 0x81000000 |
INIT_SIZE = 262144 |
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} -DINIT_ADDRESS=${INIT_ADDRESS} -DINIT_SIZE=${INIT_SIZE} |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} |
## Compile with hierarchical page tables support. |
# |
56,20 → 58,6 |
## Accepted MACHINEs |
# |
ifeq ($(MACHINE),indy) |
# GCC 4.0.1 compiled for mipsEL has problems compiling in |
# BigEndian mode with the swl/swr/lwl/lwr instructions. |
# We have to compile it with mips-sgi-irix5 to get it right. |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips --impure |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
KERNEL_LOAD_ADDRESS = 0x88002000 |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -march=r4600 |
INIT_ADDRESS = 0 |
INIT_SIZE = 0 |
endif |
ifeq ($(MACHINE),lgxemul) |
BFD_NAME = elf32-tradlittlemips |
BFD = binary |
79,9 → 67,8 |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3 |
INIT_ADDRESS = 0x81800000 |
endif |
ifeq ($(MACHINE),simics) |
# SIMICS 4kc emulation is broken, although for instructions |
123,7 → 110,6 |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/arc.c \ |
arch/$(ARCH)/src/drivers/msim.c \ |
arch/$(ARCH)/src/drivers/serial.c \ |
arch/$(ARCH)/src/smp/order.c |
/branches/dynload/kernel/arch/mips32/src/asm.S |
---|
71,6 → 71,7 |
and $v0,$v0,$v1 |
beq $a1,$v0,3f |
move $t0,$a0 |
move $t2,$a0 # save dst |
0: |
beq $a2,$zero,2f |
86,7 → 87,7 |
2: |
jr $ra |
move $v0,$a1 |
move $v0,$t2 |
3: |
addiu $v0,$a0,3 |
126,7 → 127,7 |
sb $a0,0($v1) |
jr $ra |
move $v0,$a1 |
move $v0,$t2 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
/branches/dynload/kernel/arch/mips32/src/console.c |
---|
34,19 → 34,16 |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/drivers/arc.h> |
#include <arch/drivers/serial.h> |
#include <arch/drivers/msim.h> |
void console_init(devno_t devno) |
{ |
if (!arc_console()) { |
if (serial_init()) |
serial_console(devno); |
else |
msim_console(devno); |
} |
} |
/** Acquire console back for kernel |
* |
/branches/dynload/kernel/arch/mips32/src/mips32.c |
---|
48,7 → 48,6 |
#include <sysinfo/sysinfo.h> |
#include <arch/interrupt.h> |
#include <arch/drivers/arc.h> |
#include <console/chardev.h> |
#include <arch/barrier.h> |
#include <arch/debugger.h> |
97,7 → 96,6 |
/* Initialize dispatch table */ |
exception_init(); |
arc_init(); |
/* Copy the exception vectors to the right places */ |
memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE); |
187,7 → 185,6 |
void arch_reboot(void) |
{ |
if (!arc_reboot()) |
___halt(); |
while (1) |
/branches/dynload/kernel/arch/mips32/src/mm/tlb.c |
---|
47,18 → 47,14 |
#include <align.h> |
#include <interrupt.h> |
static void tlb_refill_fail(istate_t *istate); |
static void tlb_invalid_fail(istate_t *istate); |
static void tlb_modified_fail(istate_t *istate); |
static void tlb_refill_fail(istate_t *); |
static void tlb_invalid_fail(istate_t *); |
static void tlb_modified_fail(istate_t *); |
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc); |
static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *, int *); |
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
/** Initialize TLB |
/** Initialize TLB. |
* |
* Initialize TLB. |
* Invalidate all entries and mark wired entries. |
*/ |
void tlb_arch_init(void) |
77,7 → 73,6 |
tlbwi(); |
} |
/* |
* The kernel is going to make use of some wired |
* entries (e.g. mapping kernel stacks in kseg3). |
85,10 → 80,8 |
cp0_wired_write(TLB_WIRED); |
} |
/** Process TLB Refill Exception |
/** Process TLB Refill Exception. |
* |
* Process TLB Refill Exception. |
* |
* @param istate Interrupted register context. |
*/ |
void tlb_refill(istate_t *istate) |
131,8 → 124,9 |
*/ |
pte->a = 1; |
prepare_entry_hi(&hi, asid, badvaddr); |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
tlb_prepare_entry_hi(&hi, asid, badvaddr); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
/* |
* New entry is to be inserted into TLB |
157,10 → 151,8 |
tlb_refill_fail(istate); |
} |
/** Process TLB Invalid Exception |
/** Process TLB Invalid Exception. |
* |
* Process TLB Invalid Exception. |
* |
* @param istate Interrupted register context. |
*/ |
void tlb_invalid(istate_t *istate) |
178,7 → 170,7 |
* Locate the faulting entry in TLB. |
*/ |
hi.value = cp0_entry_hi_read(); |
prepare_entry_hi(&hi, hi.asid, badvaddr); |
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
index.value = cp0_index_read(); |
221,7 → 213,8 |
*/ |
pte->a = 1; |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
/* |
* The entry is to be updated in TLB. |
241,10 → 234,8 |
tlb_invalid_fail(istate); |
} |
/** Process TLB Modified Exception |
/** Process TLB Modified Exception. |
* |
* Process TLB Modified Exception. |
* |
* @param istate Interrupted register context. |
*/ |
void tlb_modified(istate_t *istate) |
262,7 → 253,7 |
* Locate the faulting entry in TLB. |
*/ |
hi.value = cp0_entry_hi_read(); |
prepare_entry_hi(&hi, hi.asid, badvaddr); |
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
index.value = cp0_index_read(); |
296,12 → 287,6 |
} |
/* |
* Fail if the page is not writable. |
*/ |
if (!pte->w) |
goto fail; |
/* |
* Read the faulting TLB entry. |
*/ |
tlbr(); |
312,7 → 297,8 |
pte->a = 1; |
pte->d = 1; |
prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, |
pte->pfn); |
/* |
* The entry is to be updated in TLB. |
344,8 → 330,10 |
if (s) |
sym2 = s; |
fault_if_from_uspace(istate, "TLB Refill Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2); |
fault_if_from_uspace(istate, "TLB Refill Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol, sym2); |
} |
356,8 → 344,10 |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
void tlb_modified_fail(istate_t *istate) |
367,23 → 357,27 |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Modified Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
fault_if_from_uspace(istate, "TLB Modified Exception on %p", |
cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
/** Try to find PTE for faulting address |
/** 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. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @param pfrc Pointer to variable where as_page_fault() return code |
* will be stored. |
* |
* @return PTE on success, NULL otherwise. |
*/ |
pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc) |
pte_t * |
find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, |
int *pfrc) |
{ |
entry_hi_t hi; |
pte_t *pte; |
402,7 → 396,7 |
* Check if the mapping exists in page tables. |
*/ |
pte = page_mapping_find(AS, badvaddr); |
if (pte && pte->p) { |
if (pte && pte->p && (pte->w || access != PF_ACCESS_WRITE)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
425,6 → 419,7 |
page_table_lock(AS, true); |
pte = page_mapping_find(AS, badvaddr); |
ASSERT(pte && pte->p); |
ASSERT(pte->w || access != PF_ACCESS_WRITE); |
return pte; |
break; |
case AS_PF_DEFER: |
445,7 → 440,9 |
} |
} |
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn) |
void |
tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, |
uintptr_t pfn) |
{ |
lo->value = 0; |
lo->g = g; |
455,7 → 452,7 |
lo->pfn = pfn; |
} |
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
{ |
hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2); |
hi->asid = asid; |
564,7 → 561,8 |
cp0_entry_hi_write(hi_save.value); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
/** Invalidate TLB entries for specified page range belonging to specified |
* address space. |
* |
* @param asid Address space identifier. |
* @param page First page whose TLB entry is to be invalidated. |
585,7 → 583,7 |
for (i = 0; i < cnt + 1; i += 2) { |
hi.value = 0; |
prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
tlb_prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
592,7 → 590,10 |
index.value = cp0_index_read(); |
if (!index.p) { |
/* Entry was found, index register contains valid index. */ |
/* |
* Entry was found, index register contains valid |
* index. |
*/ |
tlbr(); |
lo0.value = cp0_entry_lo0_read(); |
/branches/dynload/kernel/arch/mips32/src/mm/frame.c |
---|
32,27 → 32,238 |
/** @file |
*/ |
#include <macros.h> |
#include <arch/mm/frame.h> |
#include <arch/mm/tlb.h> |
#include <interrupt.h> |
#include <mm/frame.h> |
#include <mm/asid.h> |
#include <config.h> |
#include <arch/drivers/arc.h> |
#include <arch/drivers/msim.h> |
#include <arch/drivers/serial.h> |
#include <print.h> |
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K |
#define ZERO_FRAMES 2048 |
#define ZERO_PAGE_WIDTH 18 /* 256K */ |
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH) |
#define ZERO_PAGE_ASID ASID_INVALID |
#define ZERO_PAGE_TLBI 0 |
#define ZERO_PAGE_ADDR 0 |
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1) |
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET]) |
#define ZERO_PAGE_VALUE_KSEG1(frame) (((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET]) |
#define MAX_REGIONS 32 |
typedef struct { |
pfn_t start; |
pfn_t count; |
} phys_region_t; |
static count_t phys_regions_count = 0; |
static phys_region_t phys_regions[MAX_REGIONS]; |
/** Check whether frame is available |
* |
* Returns true if given frame is generally available for use. |
* Returns false if given frame is used for physical memory |
* mapped devices and cannot be used. |
* |
*/ |
static bool frame_available(pfn_t frame) |
{ |
#if MACHINE == msim |
/* MSIM device (dprinter) */ |
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH)) |
return false; |
/* MSIM device (dkeyboard) */ |
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if MACHINE == simics |
/* Simics device (serial line) */ |
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if (MACHINE == lgxemul) || (MACHINE == bgxemul) |
/* gxemul devices */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
0x10000000, MB2SIZE(256))) |
return false; |
#endif |
return true; |
} |
/** Check whether frame is safe to write |
* |
* Returns true if given frame is safe for read/write test. |
* Returns false if given frame should not be touched. |
* |
*/ |
static bool frame_safe(pfn_t frame) |
{ |
/* Kernel structures */ |
if ((frame << ZERO_PAGE_WIDTH) < KA2PA(config.base)) |
return false; |
/* Kernel */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(config.base), config.kernel_size)) |
return false; |
/* Kernel stack */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(config.stack_base), config.stack_size)) |
return false; |
/* Init tasks */ |
bool safe = true; |
count_t i; |
for (i = 0; i < init.cnt; i++) |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(init.tasks[i].addr), init.tasks[i].size)) { |
safe = false; |
break; |
} |
return safe; |
} |
static void frame_add_region(pfn_t start_frame, pfn_t end_frame) |
{ |
if (end_frame > start_frame) { |
/* Convert 1M frames to 16K frames */ |
pfn_t first = ADDR2PFN(start_frame << ZERO_PAGE_WIDTH); |
pfn_t count = ADDR2PFN((end_frame - start_frame) << ZERO_PAGE_WIDTH); |
/* Interrupt vector frame is blacklisted */ |
pfn_t conf_frame; |
if (first == 0) |
conf_frame = 1; |
else |
conf_frame = first; |
zone_create(first, count, conf_frame, 0); |
if (phys_regions_count < MAX_REGIONS) { |
phys_regions[phys_regions_count].start = first; |
phys_regions[phys_regions_count].count = count; |
phys_regions_count++; |
} |
} |
} |
/** Create memory zones |
* |
* If ARC is known, read information from ARC, otherwise |
* assume some defaults. |
* - blacklist first FRAME because there is an exception vector |
* Walk through available 256 KB chunks of physical |
* memory and create zones. |
* |
* Note: It is assumed that the TLB is not yet being |
* used in any way, thus there is no interference. |
* |
*/ |
void frame_arch_init(void) |
{ |
if (!arc_frame_init()) { |
zone_create(0, ADDR2PFN(CONFIG_MEMORY_SIZE), 1, 0); |
/* |
* Blacklist interrupt vector |
*/ |
ipl_t ipl = interrupts_disable(); |
/* Clear and initialize TLB */ |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(0); |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
count_t i; |
for (i = 0; i < TLB_ENTRY_COUNT; i++) { |
cp0_index_write(i); |
tlbwi(); |
} |
pfn_t start_frame = 0; |
pfn_t frame; |
bool avail = true; |
/* Walk through all 1 MB frames */ |
for (frame = 0; frame < ZERO_FRAMES; frame++) { |
if (!frame_available(frame)) |
avail = false; |
else { |
if (frame_safe(frame)) { |
entry_lo_t lo0; |
entry_lo_t lo1; |
entry_hi_t hi; |
tlb_prepare_entry_lo(&lo0, false, true, true, false, frame << (ZERO_PAGE_WIDTH - 12)); |
tlb_prepare_entry_lo(&lo1, false, false, false, false, 0); |
tlb_prepare_entry_hi(&hi, ZERO_PAGE_ASID, ZERO_PAGE_ADDR); |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(lo0.value); |
cp0_entry_lo1_write(lo1.value); |
cp0_entry_hi_write(hi.value); |
cp0_index_write(ZERO_PAGE_TLBI); |
tlbwi(); |
ZERO_PAGE_VALUE = 0; |
if (ZERO_PAGE_VALUE != 0) |
avail = false; |
else { |
ZERO_PAGE_VALUE = 0xdeadbeef; |
if (ZERO_PAGE_VALUE != 0xdeadbeef) |
avail = false; |
#if (MACHINE == lgxemul) || (MACHINE == bgxemul) |
else { |
ZERO_PAGE_VALUE_KSEG1(frame) = 0xaabbccdd; |
if (ZERO_PAGE_VALUE_KSEG1(frame) != 0xaabbccdd) |
avail = false; |
} |
#endif |
} |
} |
} |
if (!avail) { |
frame_add_region(start_frame, frame); |
start_frame = frame + 1; |
avail = true; |
} |
} |
frame_add_region(start_frame, frame); |
/* Blacklist interrupt vector frame */ |
frame_mark_unavailable(0, 1); |
/* Cleanup */ |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(0); |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
cp0_index_write(ZERO_PAGE_TLBI); |
tlbwi(); |
interrupts_restore(ipl); |
} |
void physmem_print(void) |
{ |
printf("Base Size\n"); |
printf("---------- ----------\n"); |
count_t i; |
for (i = 0; i < phys_regions_count; i++) { |
printf("%#010x %10u\n", |
PFN2ADDR(phys_regions[i].start), PFN2ADDR(phys_regions[i].count)); |
} |
} |
/** @} |
*/ |
/branches/dynload/kernel/arch/mips32/src/interrupt.c |
---|
38,7 → 38,6 |
#include <arch.h> |
#include <arch/cp0.h> |
#include <time/clock.h> |
#include <arch/drivers/arc.h> |
#include <ipc/sysipc.h> |
#include <ddi/device.h> |
/branches/dynload/kernel/arch/mips32/src/drivers/arc.c |
---|
File deleted |
/branches/dynload/kernel/arch/mips32/src/drivers/msim.c |
---|
39,12 → 39,9 |
#include <arch/cp0.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0xB0000000 |
#define MSIM_KBD_ADDRESS 0xB0000000 |
#define MSIM_KBD_IRQ 2 |
static parea_t msim_parea; |
static chardev_t console; |
static irq_t msim_irq; |
158,6 → 155,16 |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS); |
msim_parea.pbase = KA2PA(MSIM_VIDEORAM); |
msim_parea.vbase = MSIM_VIDEORAM; |
msim_parea.frames = 1; |
msim_parea.cacheable = false; |
ddi_parea_register(&msim_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 3); |
sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(MSIM_VIDEORAM)); |
} |
/** @} |