/trunk/kernel/arch/sparc64/include/mm/page.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
65,6 → 65,5 |
#endif |
/** @} |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/include/mm/tte.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
77,6 → 77,5 |
#endif |
/** @} |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/include/mm/mmu.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
35,11 → 35,6 |
#ifndef __sparc64_MMU_H__ |
#define __sparc64_MMU_H__ |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <typedefs.h> |
/** LSU Control Register ASI. */ |
#define ASI_LSU_CONTROL_REG 0x45 /**< Load/Store Unit Control Register. */ |
79,7 → 74,13 |
#define VA_DMMU_VA_WATCHPOINT_REG 0x38 /**< DMMU VA data watchpoint register. */ |
#define VA_DMMU_PA_WATCHPOINT_REG 0x40 /**< DMMU PA data watchpoint register. */ |
#ifndef __ASM__ |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <typedefs.h> |
/** LSU Control Register. */ |
union lsu_cr_reg { |
uint64_t value; |
102,36 → 103,9 |
}; |
typedef union lsu_cr_reg lsu_cr_reg_t; |
#endif /* !__ASM__ */ |
#define immu_enable() immu_set(true) |
#define immu_disable() immu_set(false) |
#define dmmu_enable() dmmu_set(true) |
#define dmmu_disable() dmmu_set(false) |
/** Disable or Enable IMMU. */ |
static inline void immu_set(bool enable) |
{ |
lsu_cr_reg_t cr; |
cr.value = asi_u64_read(ASI_LSU_CONTROL_REG, 0); |
cr.im = enable; |
asi_u64_write(ASI_LSU_CONTROL_REG, 0, cr.value); |
membar(); |
} |
/** Disable or Enable DMMU. */ |
static inline void dmmu_set(bool enable) |
{ |
lsu_cr_reg_t cr; |
cr.value = asi_u64_read(ASI_LSU_CONTROL_REG, 0); |
cr.dm = enable; |
asi_u64_write(ASI_LSU_CONTROL_REG, 0, cr.value); |
membar(); |
} |
#endif |
/** @} |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/include/mm/tlb.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
227,7 → 227,7 |
reg.value = 0; |
reg.tlb_entry = entry; |
asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value); |
flush(); |
membar(); |
} |
/** Read IMMU TLB Tag Read Register. |
286,7 → 286,7 |
static inline void dtlb_tag_access_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v); |
flush(); |
membar(); |
} |
/** Read DMMU TLB Tag Access Register. |
316,7 → 316,7 |
static inline void dtlb_data_in_write(uint64_t v) |
{ |
asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v); |
flush(); |
membar(); |
} |
/** Read ITLB Synchronous Fault Status Register. |
354,7 → 354,7 |
static inline void dtlb_sfsr_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v); |
flush(); |
membar(); |
} |
/** Read DTLB Synchronous Fault Address Register. |
407,7 → 407,7 |
da.vpn = pg.vpn; |
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); |
flush(); |
membar(); |
} |
extern void fast_instruction_access_mmu_miss(void); |
418,6 → 418,5 |
#endif |
/** @} |
/** @} |
*/ |
/trunk/kernel/arch/sparc64/include/barrier.h |
---|
54,11 → 54,7 |
* However, JPS1 implementations are free to ignore the trap. |
*/ |
/* |
* %i7 should provide address that is always mapped in DTLB |
* as it is a pointer to kernel code. |
*/ |
__asm__ volatile ("flush %i7\n"); |
__asm__ volatile ("flush %0\n" :: "r" (0x400000)); |
} |
/** Memory Barrier instruction. */ |
/trunk/kernel/arch/sparc64/src/console.c |
---|
54,7 → 54,9 |
{ |
stdin = NULL; |
kbd_init(); |
if (bootinfo.keyboard.addr) |
kbd_init(); |
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, |
bootinfo.screen.bpp, bootinfo.screen.scanline); |
} |
65,6 → 67,9 |
*/ |
void kkbdpoll(void *arg) |
{ |
if (!bootinfo.keyboard.addr) |
return; |
while (1) { |
i8042_poll(); |
thread_usleep(KEYBOARD_POLL_PAUSE); |
/trunk/kernel/arch/sparc64/src/sparc64.c |
---|
96,14 → 96,13 |
* Initialize ITLB and DTLB and switch to kernel |
* trap table. |
* |
* The goal of this function is to disable MMU |
* so that both TLBs can be purged and new |
* kernel 4M locked entry can be installed. |
* After TLB is initialized, MMU is enabled |
* again. |
* First, demap context 0 and install the |
* global 4M locked kernel mapping. |
* |
* Switching MMU off imposes the requirement for |
* the kernel to run in identity mapped environment. |
* Second, prepare a temporary IMMU mapping in |
* context 1, switch to it, demap context 0, |
* install the global 4M locked kernel mapping |
* in context 0 and switch back to context 0. |
* |
* @param base Base address that will be hardwired in both TLBs. |
*/ |
114,27 → 113,21 |
frame_address_t fr; |
page_address_t pg; |
/* |
* Switch to the kernel trap table. |
*/ |
trap_switch_trap_table(); |
fr.address = base; |
pg.address = base; |
immu_disable(); |
dmmu_disable(); |
/* |
* Demap everything, especially OpenFirmware. |
*/ |
itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0); |
dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0); |
/* |
* We do identity mapping of 4M-page at 4M. |
*/ |
tag.value = ASID_KERNEL; |
tag.value = 0; |
tag.context = 0; |
tag.vpn = pg.vpn; |
itlb_tag_access_write(tag.value); |
dtlb_tag_access_write(tag.value); |
data.value = 0; |
data.v = true; |
data.size = PAGESIZE_4M; |
141,25 → 134,43 |
data.pfn = fr.pfn; |
data.l = true; |
data.cp = 1; |
data.cv = 1; |
data.cv = 0; |
data.p = true; |
data.w = true; |
data.g = true; |
itlb_data_in_write(data.value); |
/* |
* Straightforwardly demap DMUU context 0, |
* and replace it with the locked kernel mapping. |
*/ |
dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0); |
dtlb_tag_access_write(tag.value); |
dtlb_data_in_write(data.value); |
/* |
* Register window traps can occur before MMU is enabled again. |
* This ensures that any such traps will be handled from |
* kernel identity mapped trap handler. |
* Install kernel code mapping in context 1 |
* and switch to it. |
*/ |
trap_switch_trap_table(); |
tag.context = 1; |
data.g = false; |
itlb_tag_access_write(tag.value); |
itlb_data_in_write(data.value); |
mmu_primary_context_write(1); |
tlb_invalidate_all(); |
dmmu_enable(); |
immu_enable(); |
/* |
* Demap old context 0. |
*/ |
itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_NUCLEUS, 0); |
/* |
* Install the locked kernel mapping in context 0 |
* and switch to it. |
*/ |
tag.context = 0; |
data.g = true; |
itlb_tag_access_write(tag.value); |
itlb_data_in_write(data.value); |
mmu_primary_context_write(0); |
} |
/** @} |
/trunk/kernel/arch/sparc64/src/start.S |
---|
71,14 → 71,14 |
call memcpy |
nop |
set kernel_image_start, %o0 |
/* |
* Take over control of identity mapping. |
* Take over control of trap table. |
* Take over control of MMU. |
* |
* After this call, the kernel is entirely self-sufficient |
* and independent on OpenFirmware. |
* First, take over DMMU for which we don't need to issue |
* any FLUSH instructions. Because of that, we can |
* demap the old DTLB pretty straightforwardly. |
*/ |
set kernel_image_start, %o0 |
call take_over_tlb_and_tt |
nop |