📄 ppc821.s
字号:
// Should the uncached space also be marked as guarded?
//
// (r0) = saved CR value
// (r1) = missing virtual address
// (M_TW) = saved R0
// (SPRG0) = saved R1
// (SPRG3) = saved R3
//
// For CPU2, this is moved to DTBError
//
#if !defined(CPU2_ERRATUM)
dtmh50:
bt- 1, dtmh40 // Bit 30 set - Invalid address
li r3, PAGE_8MB | PAGE_VALID
mtspr MD_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 | 0x1f8
rlwimi r3, r1, 4, 2 // insert cache-inhibit bit
dtmh55:
mtspr MD_RPN, r3
mtcrf 0xff, r0 // restore condition register
mfspr r0, M_TW
mfspr r1, SPRG0
mfspr r3, SPRG3
rfi
#endif
.org DTBMiss+0x100 // Fill out the vector
// Instruction TLB error 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
//
ITBError:
mtspr SPRG1, r4
mtspr SPRG2, r5
li r4, ID_CPAGE_FAULT // (r4) = ITLB error interrupt code
mfspr r5, SRR0
ba KPageGeneralHandler
//
// For CPU2, we moved this from ITBMiss because the handler got
// too big.
//
#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
li r1, 0x2b80
stw r1, kErrata(r0)
lwz r1, kErrata(r0)
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:
li r1, 0x2d80
stw r1, kErrata(r0)
lwz r1, kErrata(r0)
mtspr MI_RPN, r3
mtcrf 0xff, r0 // restore condition register
mfspr r0, M_TW
mfspr r1, SPRG0
mfspr r3, SPRG3
rfi
#endif
.org ITBError + 0x100
// Data TLB error handler
//
// Entry: (MSR) External interrupts disabled
// Instruction Relocate OFF
// Data Relocate OFF
// (DAR) Instruction address at time of interrupt
// (SRR1) MSR at time of interrupt
//
DTBError:
mtspr SPRG1, r4
mtspr SPRG2, r5
li r4, ID_DPAGE_FAULT
mfspr r5, DAR
ba KPageGeneralHandler // Call the general exception handler
//
// Moved from DTBMiss because DTBMiss got too big
//
#if defined(CPU2_ERRATUM)
dtmh50:
bt- 1, dtmh40 // Bit 30 set - Invalid address
li r3, 0x3b80
stw r3, kErrata(r0)
lwz r3, kErrata(r0)
li r3, PAGE_8MB | PAGE_VALID
mtspr MD_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 | 0x1f8
rlwimi r3, r1, 4, 2 // insert cache-inhibit bit
dtmh55:
li r1, 0x3d80
stw r1, kErrata(r0)
lwz r1, kErrata(r0)
mtspr MD_RPN, r3
mtcrf 0xff, r0 // restore condition register
mfspr r0, M_TW
mfspr r1, SPRG0
mfspr r3, SPRG3
rfi
#endif
.org DTBError+0x100
//
// TLBInit
//
// Perform the processor specific TLB Initialization:
//
// Any processor specific TLB initialization is performed here, and two
// fixed translations are created:
//
// 1) KSEG Mapping. All address with bit 0 set are mapped 1-to-1
//
// 2) KPage Mapping. The KPAGE is mapped Virtual=Physical. The mapping
// is writable and executable in kernel mode, but
// read-only in user mode
//
// On Entry:
// (r3) Physical address of OEMMemoryMap
//
LEAF_ENTRY(TLBInit)
// Translate OEMMemoryMap to KPfnMap
// (r4) Virtual Address
// (r5) Physical Address
// (r6) Size
KPFNMapStart:
// Get entry size
lwz r6, 8(r3)
// Divide size by 16. This gives us the number of
// KPFN entries covered.
srawi r6, r6, 4
// If the size is zero, we're done
cmpi 0, 0, r6, 0
beq KPFNMapDone
// Get physical and virtual address
lwz r4, 0(r3)
lwz r5, 4(r3)
// For each address, rotate the upper byte into the low byte
// and mask it off.
rlwinm r4, r4, 8, 0x0000001F // KSEG address high byte. Bits 31-29 are always 100.
rlwinm r5, r5, 8, 0x000000FF // Physical address high byte.
// Now fill the KPFN entries
mtctr r6
FillLoop:
stb r5, kPFNMap(r4)
addi r4, r4, 1
addi r5, r5, 1
bdnz FillLoop
// Next entry...
addi r3, r3, 12
b KPFNMapStart
KPFNMapDone:
lis r3, 0xF000
mtspr SPRG0, r3 // setup "stack" for nested TLB exceptions
tlbia // clear out all TLB entries
li r3, 0x5555
oris r3, r3, 0x5555
mtspr MI_AP, r3 // all instr. access based on Page tables
mtspr MD_AP, r3 // all data access based on Page tables
// Load reserved entry for KPage into the Data TLB.
li r3, 0x1f00
mtspr MD_CTR, r3 // select entry #31
li r3, KPAGE_BASE | 0x200
mtspr MD_EPN, r3
li r3, PAGE_VALID
mtspr MD_TWC, r3
li r3, KPAGE_BASE|PG_VALID_MASK|PG_GLOBAL_MASK|PG_CACHE|PG_PROT_URO_KRW|PG_DIRTY_MASK
mtspr MD_RPN, r3 // load the entry
lis r3, 0x0C00
mtspr MD_CTR, r3 // set RSV4D bit to lock the entry
LEAF_EXIT(TLBInit)
//
// FlushTLB
//
// Flush all TLB entries.
//
LEAF_ENTRY(FlushTLB)
isync // Sync the I-stream
tlbia // Invalidate all entries
isync // Re-Sync the I-stream
LEAF_EXIT(FlushTLB)
LEAF_ENTRY(SetCASID)
// SetCASID - set M_CASID register
//
// This function is needed because the C compiler won't accept registers
// it doesn't know about in the _sregister_set() call.
//
// Entry (r3) = new address space ID
// Exit none
// Uses none
#if defined(CPU2_ERRATUM)
li r4, 0x3380
stw r4, kErrata(r0)
lwz r4, kErrata(r0)
#endif
mtspr M_CASID, r3
LEAF_EXIT(SetCASID)
//
// LEAF_ENTRY(CPUIdentify)
//
// Returns information about the current processor.
//
// Entry none
// Exit (r3) = Processor type (821 or 823)
//
LEAF_ENTRY(CPUIdentify)
// Detect PPC 821 vs. PPC823 using the IMMR. The Partnum field
// (IMMR[16:23]) on the PPC 823 is 0x20. On the PPC 821, it's 0.
mfspr r4, IMMR // Get IMMR
rlwinm. r4, r4, 0, 0x00002000 // Mask off the important bit
li r3, 821 // Assume 821
beq ProcType821 // Bit is clear so have an 821
ProcType823: // Got an 823
li r3, 823
ProcType821:
LEAF_EXIT(CPUIdentify)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -