📄 ppc821.s
字号:
// TITLE("TLB Management and support routines")
//++
//
//
// Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
//
//
// Module Name:
//
// ppc821.s
//
// Abstract:
//
// Initialization of the TLB support for the PPC821 kernel
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
//--
#include "mem_ppc.h"
#include "mmu821.h"
//
// Definition of Special Purpose Registers (SPRs) used on PPC821
//
#define DSISR 18
#define DAR 19
#define IMMR 638
#define INVALID_PAGE 0x2f1
//#define CPU2_ERRATUM 1
//
// See the MPC821 errata for information on the CPU2 hardware issue. The
// code inside the conditional CPU2_ERRATUM is specific to this issue.
//
#if defined(CPU2_ERRATUM)
// We need a little memory that we can guarantee will always be present.
// This is located in the kernel data structure 'reserved' block.
#define kErrata 0x5AF0
#endif
//
// The TLB Handlers are defined here and then copied into low memory
// The four handlers ITBMiss, DTBMiss, ITBError, and DTBError are copied
// into the correct location for each processor
// Each vector must be limited to 256 bytes (64 instructions)
//
#define ITBMissVector 0x1100
#define DTBMissVector 0x1200
#define ITBErrorVector 0x1300
#define DTBErrorVector 0x1400
.text
// Instruction TLB miss handler
//
// Entry: (MSR) External interrupts disabled
// Instruction Relocate OFF
// Data Relocate OFF
// (SRR0) Instruction address at time of interrupt
// (SRR1) MSR at time of interrupt
//
// Exit:
//
// Uses: M_TW
ITBMiss:
#if defined(CPU2_ERRATUM)
mtspr SPRG0, r1
li r1, 0x3f80
stw r1, kErrata(r0)
lwz r1, kErrata(r0)
mtspr M_TW, r0
#else
mtspr M_TW, r0 // save r0 for a scratch register
mtspr SPRG0, r1
#endif
mfspr r1, SRR0 // (r1) = fauling address
mfcr r0 // (r0) = saved condition register
mtcrf 0x80, r1 // (CR0) = faulting address upper nibble
mtspr SPRG3, r3
bt- 0, itmh50 // high bit of address is set
mtspr SPRG1, r4
mtspr SPRG2, r5
// Lookup a user virtual address in the kernel virtual memory tables to find the
// physical address translation to be loaded into the TLB.
rlwinm r3, r1, (32-VA_SECTION)+2, SECTION_MASK*4 // (r3) = section index
lwz r4, SectionTable(r3) // (r4) = ptr to SECTION
lwz r5, CurAKey(0) // (r5) = current access key
rlwinm r3, r1, (32-VA_BLOCK)+2, BLOCK_MASK*4 // (r3) = block index
rlwinm r4, r4, 0, 0x1fffffff // make it physical
lwzx r3, r3, r4 // (r3) = ptr to MEMBLOCK structure
rlwinm r4, r1, (32-VA_PAGE)+2, PAGE_MASK*4 // (r4) = page index
rlwinm r3, r3, 0, 0x1fffffff // make it physical
cmplwi r3, 0x1000
blt- itmh40 // invalid block address
add r4, r3, r4
lwz r3, mb_lock(r3) // (r3) = access lock for memory block
lwz r4, mb_pages(r4) // (r4) = PTE entry for the page
and. r5, r5, r3
beq- itmh40 // access not allowed
andi. r5, r4, PAGE_VALID
beq- itmh40 // invalid entry
itmh30:
#if defined(CPU2_ERRATUM)
li r1, 0x2d80
stw r1, kErrata(r0)
lwz r1, kErrata(r0)
#endif
mtspr MI_RPN, r4 // add entry to the TLB
// New entry loaded into the TLB. Restore registers and continue.
//
// (r0) = condition register
// (M_TW) = saved R0
// (SPRG0) = saved R1
// (SPRG1) = saved R4
// (SPRG2) = saved R5
// (SPRG3) = saved R3
mtcrf 0xff, r0 // restore condition register
mfspr r0, M_TW
mfspr r1, SPRG0
mfspr r4, SPRG1
mfspr r5, SPRG2
mfspr r3, SPRG3
rfi
// Invalid address reference. Load invalid entry into the TLB and continue.
// This will cause an ITLB error interrupt.
itmh40: mtcrf 0xff, r0 // restore condition register
mfspr r0, M_TW
mfspr r1, SPRG0
mfspr r3, SPRG3
li r4, ID_CPAGE_FAULT // (r4) = ITLB error interrupt code
mfspr r5, SRR0 // (r5) = address of fault
ba KPageGeneralHandler
// Address in kernel space. Check if kernel server call or reference to
// an "un-mapped" space. For an "un-mapped" space reference, generate
// a large (8mb) TLB entry to map the region. For an api call, jump to
// the initial api handler code in the KPage.
//
// (r0) = saved CR value
// (r1) = missing virtual address
// (M_TW) = saved R0
// (SPRG0) = saved R1
// (SPRG3) = saved R3
//
// For CPU2, this is too big, so we moved it to spare space in ITBError
//
#if !defined(CPU2_ERRATUM)
itmh50:
lis r3, API_MAX >> 16
ori r3, r3, API_MAX & 0xFFFF
cmplw r3, r1
bgt- itmKMap // not an api call or return
// Setup to invoke the API call or return code.
//
//NOTE: Since this is a C or C++ function call or return, it is not necessary to restore
// R12 and CR0.
subi r11, r1, FIRST_METHOD // (r11) = iMethod * API_SCALE
mfspr r12, SRR1
mfspr r1, SPRG0
mfspr r3, SPRG3
ba KPageAPIHandler
itmKMap:
li r3, PAGE_8MB | PAGE_VALID
mtspr MI_TWC, r3 // setup for 8mb valid page
rlwinm r3, r1, 8, 0x1f // (r3) = 16M page number
lbz r3, kPFNMap(r3) // (r3) = physical page number
rlwinm r3, r3, 24, 0xff000000 // Puts physical page number into high byte
rlwimi r3, r1, 0, 0x00800000 // Preserve 8M bit
ori r3, r3, PAGE_VALID | PAGE_SHARED | 0xf8
rlwimi r3, r1, 4, 2 // insert cache-inhibit bit
itmh55:
mtspr MI_RPN, r3
mtcrf 0xff, r0 // restore condition register
mfspr r0, M_TW
mfspr r1, SPRG0
mfspr r3, SPRG3
rfi
#endif
.org ITBMiss+0x100 // Fill out the vector
// Data TLB miss handler
//
// Entry: (MSR) External interrupts disabled
// Instruction Relocate OFF
// Data Relocate OFF
// (SRR0) Instruction address at time of interrupt
// (SRR1) MSR at time of interrupt
//
// Exit:
//
// Uses: SPRG3 and M_TW
DTBMiss:
#if defined(CPU2_ERRATUM)
mtspr SPRG0, r1
li r1, 0x3f80
stw r1, kErrata(r0)
lwz r1, kErrata(r0)
mtspr M_TW, r0
#else
mtspr M_TW, r0 // save r0 for a scratch register
mtspr SPRG0, r1
#endif
mfspr r1, MD_EPN // (r1) = fauling address
mfcr r0 // (r0) = saved condition register
mtcrf 0x80, r1 // (CR0) = faulting address upper nibble
mtspr SPRG3, r3
bt- 0, dtmh50 // high bit of address is set
mtspr SPRG1, r4
mtspr SPRG2, r5
// Lookup a user virtual address in the kernel virtual memory tables to find the
// physical address translation to be loaded into the TLB.
rlwinm r3, r1, (32-VA_SECTION)+2, SECTION_MASK*4 // (r3) = section index
lwz r4, SectionTable(r3) // (r4) = ptr to SECTION
rlwinm r3, r1, (32-VA_BLOCK)+2, BLOCK_MASK*4 // (r3) = block index
rlwinm r4, r4, 0, 0x1fffffff // make it physical
lwzx r3, r3, r4 // (r3) = ptr to MEMBLOCK structure
rlwinm r4, r1, (32-VA_PAGE)+2, PAGE_MASK*4 // (r4) = page index
rlwinm r3, r3, 0, 0x1fffffff // make it physical
cmplwi r3, 0x1000
lwz r1, CurAKey(0) // (r1) = current access key
blt- dtmh40 // invalid block address
add r4, r3, r4
lwz r3, mb_lock(r3) // (r3) = access lock for memory block
lwz r4, mb_pages(r4) // (r4) = PTE entry for the page
and. r1, r1, r3
beq- dtmh40 // access not allowed
andi. r1, r4, PAGE_VALID
beq- dtmh40 // invalid entry
dtmh30:
#if defined(CPU2_ERRATUM)
li r1, 0x3d80
stw r1, kErrata(r0)
lwz r1, kErrata(r0)
#endif
mtspr MD_RPN, r4 // add entry to the TLB
// New entry loaded into the TLB. Restore registers and continue.
//
// (r0) = condition register
// (M_TW) = saved R0
// (SPRG0) = saved R1
// (SPRG1) = saved R4
// (SPRG2) = saved R5
// (SPRG3) = saved R3
mtcrf 0xff, r0 // restore condition register
mfspr r0, M_TW
mfspr r1, SPRG0
mfspr r4, SPRG1
mfspr r5, SPRG2
mfspr r3, SPRG3
rfi
// Invalid address reference. Load invalid entry into the TLB and continue.
// This will cause an ITLB error interrupt.
dtmh40:
mtcrf 0xff, r0 // restore condition register
mfspr r0, M_TW
mfspr r1, SPRG0
mfspr r3, SPRG3
li r4, ID_DPAGE_FAULT // (r4) = ITLB error interrupt code
mfspr r5, DAR
ba KPageGeneralHandler
// Address in kernel space. For an "un-mapped" space reference, generate
// a large (8mb) TLB entry to map the region.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -