Commit d4c186bd authored by Paul Mackerras's avatar Paul Mackerras

Merge bk://ppc@ppc.bkbits.net/for-linus-ppc

into samba.org:/home/paulus/kernel/for-linus-ppc
parents 230ac729 2cd038d6
This diff is collapsed.
......@@ -32,6 +32,7 @@ head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o
head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o
head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o
head-$(CONFIG_POWER4) += arch/ppc/kernel/idle_power4.o
core-y += arch/ppc/kernel/ arch/ppc/platforms/ \
arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
......
......@@ -198,7 +198,7 @@ udelay:
* timebase_period_ns defaults to 60 (16.6MHz) */
lis r5,timebase_period_ns@ha
lwz r5,timebase_period_ns@l(r5)
addi r4,r4,r5
add r4,r4,r5
addi r4,r4,-1
divw r4,r4,r5 /* BUS ticks */
1: mftbu r5
......
......@@ -15,6 +15,7 @@ extra-$(CONFIG_40x) := head_4xx.o
extra-$(CONFIG_44x) := head_44x.o
extra-$(CONFIG_8xx) := head_8xx.o
extra-$(CONFIG_6xx) += idle_6xx.o
extra-$(CONFIG_POWER4) += idle_power4.o
extra-y += vmlinux.lds.s
obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
......
......@@ -28,11 +28,13 @@ extern void __setup_cpu_7400(unsigned long offset, int cpu_nr, struct cpu_spec*
extern void __setup_cpu_7410(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_745x(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_power3(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_power4(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_ppc970(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_8xx(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
!defined(CONFIG_POWER3))
!defined(CONFIG_POWER3) && !defined(CONFIG_POWER4))
/* This table only contains "desktop" CPUs, it need to be filled with embedded
* ones as well...
......@@ -44,9 +46,11 @@ extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spe
* support
*/
#ifdef CONFIG_ALTIVEC
#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC
#define PPC_FEATURE_ALTIVEC_COMP PPC_FEATURE_HAS_ALTIVEC
#else
#define CPU_FTR_ALTIVEC_COMP 0
#define CPU_FTR_ALTIVEC_COMP 0
#define PPC_FEATURE_ALTIVEC_COMP 0
#endif
struct cpu_spec cpu_specs[] = {
......@@ -195,7 +199,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
32, 32,
__setup_cpu_7400
},
......@@ -204,7 +208,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32,
__setup_cpu_7400
},
......@@ -213,7 +217,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP | CPU_FTR_HPTE_TABLE |
CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32,
__setup_cpu_7410
},
......@@ -222,7 +226,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32,
__setup_cpu_745x
},
......@@ -232,7 +236,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_L3_DISABLE_NAP,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
32, 32,
__setup_cpu_745x
},
......@@ -241,7 +245,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_NAP |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32,
__setup_cpu_745x
},
......@@ -250,7 +254,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32,
__setup_cpu_745x
},
......@@ -260,7 +264,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_L3_DISABLE_NAP | CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32,
__setup_cpu_745x
},
......@@ -270,7 +274,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP
32, 32,
__setup_cpu_745x
},
......@@ -280,7 +284,7 @@ struct cpu_spec cpu_specs[] = {
CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP | CPU_FTR_L3CR |
CPU_FTR_HPTE_TABLE | CPU_FTR_SPEC7450 | CPU_FTR_NAP_DISABLE_L2_PR |
CPU_FTR_HAS_HIGH_BATS,
COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC,
COMMON_PPC | PPC_FEATURE_ALTIVEC_COMP,
32, 32,
__setup_cpu_745x
},
......@@ -329,6 +333,23 @@ struct cpu_spec cpu_specs[] = {
__setup_cpu_power3
},
#endif /* CONFIG_PPC64BRIDGE */
#ifdef CONFIG_POWER4
{ /* Power4 */
0xffff0000, 0x00350000, "Power4",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE,
COMMON_PPC | PPC_FEATURE_64,
128, 128,
__setup_cpu_power4
},
{ /* PPC970 */
0xffff0000, 0x00390000, "PPC970",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_HPTE_TABLE |
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP,
COMMON_PPC | PPC_FEATURE_64 | PPC_FEATURE_ALTIVEC_COMP,
128, 128,
__setup_cpu_ppc970
},
#endif /* CONFIG_POWER4 */
#ifdef CONFIG_8xx
{ /* 8xx */
0xffff0000, 0x00500000, "8xx",
......
......@@ -140,6 +140,18 @@ __start:
mr r28,r6
mr r27,r7
li r24,0 /* cpu # */
#ifdef CONFIG_POWER4
/*
* On the PPC970, we have to turn off real-mode cache inhibit
* early, before we first turn the MMU off.
*/
mfspr r0,SPRN_PVR
srwi r0,r0,16
cmpwi r0,0x39
beql ppc970_setup_hid
#endif /* CONFIG_POWER4 */
/*
* early_init() does the early machine identification and does
* the necessary low-level setup and clears the BSS
......@@ -160,6 +172,7 @@ __start:
*/
bl mmu_off
__after_mmu_off:
#ifndef CONFIG_POWER4
bl clear_bats
bl flush_tlbs
......@@ -167,6 +180,28 @@ __after_mmu_off:
#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
bl setup_disp_bat
#endif
#else /* CONFIG_POWER4 */
/*
* Load up the SDR1 and segment register values now
* since we don't have the BATs.
* Also make sure we are running in 32-bit mode.
*/
bl reloc_offset
addis r14,r3,_SDR1@ha /* get the value from _SDR1 */
lwz r14,_SDR1@l(r14) /* assume hash table below 4GB */
mtspr SDR1,r14
slbia
lis r4,0x2000 /* set pseudo-segment reg 12 */
ori r5,r4,0x0ccc
mtsr 12,r5
ori r4,r4,0x0888 /* set pseudo-segment reg 8 */
mtsr 8,r4 /* (for access to serial port) */
mfmsr r0
clrldi r0,r0,1
sync
mtmsr r0
isync
#endif /* CONFIG_POWER4 */
/*
* Call setup_cpu for CPU 0 and initialize 6xx Idle
......@@ -178,6 +213,10 @@ __after_mmu_off:
bl reloc_offset
bl init_idle_6xx
#endif /* CONFIG_6xx */
#ifdef CONFIG_POWER4
bl reloc_offset
bl init_idle_power4
#endif /* CONFIG_POWER4 */
#ifndef CONFIG_APUS
......@@ -683,12 +722,21 @@ DataStoreTLBMiss:
mtcrf 0x80,r3
rfi
#ifndef CONFIG_ALTIVEC
#define AltivecAssistException UnknownException
#endif
EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, EXC_XFER_EE)
EXCEPTION(0x1400, SMI, SMIException, EXC_XFER_EE)
EXCEPTION(0x1500, Trap_15, UnknownException, EXC_XFER_EE)
#ifdef CONFIG_POWER4
EXCEPTION(0x1600, Trap_16, UnknownException, EXC_XFER_EE)
EXCEPTION(0x1700, Trap_17, AltivecAssistException, EXC_XFER_EE)
EXCEPTION(0x1800, Trap_18, TAUException, EXC_XFER_STD)
#else /* !CONFIG_POWER4 */
EXCEPTION(0x1600, Trap_16, AltivecAssistException, EXC_XFER_EE)
EXCEPTION(0x1700, Trap_17, TAUException, EXC_XFER_STD)
EXCEPTION(0x1800, Trap_18, UnknownException, EXC_XFER_EE)
#endif /* CONFIG_POWER4 */
EXCEPTION(0x1900, Trap_19, UnknownException, EXC_XFER_EE)
EXCEPTION(0x1a00, Trap_1a, UnknownException, EXC_XFER_EE)
EXCEPTION(0x1b00, Trap_1b, UnknownException, EXC_XFER_EE)
......@@ -1199,6 +1247,10 @@ __secondary_start:
lis r3,-KERNELBASE@h
bl init_idle_6xx
#endif /* CONFIG_6xx */
#ifdef CONFIG_POWER4
lis r3,-KERNELBASE@h
bl init_idle_power4
#endif /* CONFIG_POWER4 */
/* get current_thread_info and current */
lis r1,secondary_ti@ha
......@@ -1226,6 +1278,7 @@ __secondary_start:
/* enable MMU and jump to start_secondary */
li r4,MSR_KERNEL
FIX_SRR1(r4,r5)
lis r3,start_secondary@h
ori r3,r3,start_secondary@l
mtspr SRR0,r3
......@@ -1240,6 +1293,10 @@ __secondary_start:
*/
_GLOBAL(__setup_cpu_power3)
blr
_GLOBAL(__setup_cpu_power4)
blr
_GLOBAL(__setup_cpu_ppc970)
blr
_GLOBAL(__setup_cpu_generic)
blr
......@@ -1247,6 +1304,13 @@ _GLOBAL(__setup_cpu_generic)
_GLOBAL(__save_cpu_setup)
blr
_GLOBAL(__restore_cpu_setup)
#ifdef CONFIG_POWER4
/* turn off real-mode cache inhibit on the PPC970 */
mfspr r0,SPRN_PVR
srwi r0,r0,16
cmpwi r0,0x39
beq ppc970_setup_hid
#endif
blr
#endif /* CONFIG_6xx */
......@@ -1256,6 +1320,11 @@ _GLOBAL(__restore_cpu_setup)
* IR=0 and DR=0.
*/
load_up_mmu:
sync /* Force all PTE updates to finish */
isync
tlbia /* Clear all TLB entries */
sync /* wait for tlbia/tlbie to finish */
TLBSYNC /* ... on all CPUs */
/* Load the SDR1 register (hash table base & size) */
lis r6,_SDR1@ha
tophys(r6,r6)
......@@ -1274,6 +1343,7 @@ load_up_mmu:
addi r3,r3,0x111 /* increment VSID */
addis r4,r4,0x1000 /* address of next segment */
bdnz 3b
#ifndef CONFIG_POWER4
/* Load the BAT registers with the values set up by MMU_init.
MMU_init takes care of whether we're on a 601 or not. */
mfpvr r3
......@@ -1286,6 +1356,7 @@ load_up_mmu:
LOAD_BAT(1,r3,r4,r5)
LOAD_BAT(2,r3,r4,r5)
LOAD_BAT(3,r3,r4,r5)
#endif /* CONFIG_POWER4 */
blr
/*
......@@ -1349,15 +1420,9 @@ start_here:
SYNC
RFI
/* Load up the kernel context */
2:
sync /* Force all PTE updates to finish */
ISYNC_601
tlbia /* Clear all TLB entries */
sync /* wait for tlbia/tlbie to finish */
TLBSYNC /* ... on all CPUs */
bl load_up_mmu
2: bl load_up_mmu
#ifdef CONFIG_BDI_SWITCH
/* Add helper information for the Abatron bdiGDB debugger.
* We do this here because we know the mmu is disabled, and
* will be enabled for real in just a few instructions.
......@@ -1369,6 +1434,7 @@ start_here:
ori r6, r6, swapper_pg_dir@l
tophys(r5, r5)
stw r6, 0(r5)
#endif /* CONFIG_BDI_SWITCH */
/* Now turn on the MMU for real! */
li r4,MSR_KERNEL
......@@ -1493,6 +1559,7 @@ mmu_off:
sync
RFI
#ifndef CONFIG_POWER4
/*
* Use the first pair of BAT registers to map the 1st 16MB
* of RAM to KERNELBASE. From this point on we can't safely
......@@ -1566,6 +1633,41 @@ setup_disp_bat:
#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
#else /* CONFIG_POWER4 */
ppc970_setup_hid:
li r0,0
sync
mtspr 0x3f4,r0
isync
sync
mtspr 0x3f6,r0
isync
mfspr r0,SPRN_HID0
li r11,1 /* clear DOZE, NAP and SLEEP */
rldimi r0,r11,52,8 /* set DPM */
mtspr SPRN_HID0,r0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
sync
isync
mfspr r0,SPRN_HID1
li r11,0x1200 /* enable i-fetch cacheability */
sldi r11,r11,44 /* and prefetch */
or r0,r0,r11
mtspr SPRN_HID1,r0
mtspr SPRN_HID1,r0
isync
li r0,0
sync
mtspr 0x137,0
isync
blr
#endif /* CONFIG_POWER4 */
#ifdef CONFIG_8260
/* Jump into the system reset for the rom.
* We first disable the MMU, and then jump to the ROM reset address.
......
/*
* This file contains the power_save function for 6xx & 7xxx CPUs
* rewritten in assembler
*
* Warning ! This code assumes that if your machine has a 750fx
* it will have PLL 1 set to low speed mode (used during NAP/DOZE).
* if this is not the case some additional changes will have to
* be done to check a runtime var (a bit like powersave-nap)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/config.h>
#include <linux/threads.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/cputable.h>
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
#undef DEBUG
.text
/*
* Init idle, called at early CPU setup time from head.S for each CPU
* Make sure no rest of NAP mode remains in HID0, save default
* values for some CPU specific registers. Called with r24
* containing CPU number and r3 reloc offset
*/
.globl init_idle_power4
init_idle_power4:
BEGIN_FTR_SECTION
mfspr r4,SPRN_HID0
rlwinm r4,r4,0,10,8 /* Clear NAP */
mtspr SPRN_HID0, r4
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
blr
/*
* Here is the power_save_6xx function. This could eventually be
* split into several functions & changing the function pointer
* depending on the various features.
*/
.globl power4_idle
power4_idle:
/* Check if we can nap or doze, put HID0 mask in r3
*/
lis r3, 0
BEGIN_FTR_SECTION
/* We must dynamically check for the NAP feature as it
* can be cleared by CPU init after the fixups are done
*/
lis r4,cur_cpu_spec@ha
lwz r4,cur_cpu_spec@l(r4)
lwz r4,CPU_SPEC_FEATURES(r4)
andi. r0,r4,CPU_FTR_CAN_NAP
beq 1f
/* Now check if user or arch enabled NAP mode */
lis r4,powersave_nap@ha
lwz r4,powersave_nap@l(r4)
cmpi 0,r4,0
beq 1f
lis r3,HID0_NAP@h
1:
END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
cmpi 0,r3,0
beqlr
/* Clear MSR:EE */
mfmsr r7
rlwinm r0,r7,0,17,15
mtmsr r0
/* Check current_thread_info()->flags */
rlwinm r4,r1,0,0,18
lwz r4,TI_FLAGS(r4)
andi. r0,r4,_TIF_NEED_RESCHED
beq 1f
mtmsr r7 /* out of line this ? */
blr
1:
/* Go to NAP now */
mfspr r4,SPRN_HID0
lis r5,(HID0_NAP|HID0_SLEEP)@h
andc r4,r4,r5
or r4,r4,r3
oris r4,r4,HID0_DPM@h /* that should be done once for all */
mtspr SPRN_HID0,r4
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
mfspr r0,SPRN_HID0
BEGIN_FTR_SECTION
DSSALL
sync
END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
ori r7,r7,MSR_EE /* Could be ommited (already set) */
oris r7,r7,MSR_POW@h
sync
isync
mtmsr r7
isync
sync
blr
.globl powersave_nap
powersave_nap:
.long 0
......@@ -54,6 +54,7 @@ extern void kgdb_map_scc(void);
#endif
extern void ppc6xx_idle(void);
extern void power4_idle(void);
extern boot_infos_t *boot_infos;
char saved_command_line[256];
......@@ -529,9 +530,12 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5,
strcpy(cmd_line, CONFIG_CMDLINE);
#endif /* CONFIG_CMDLINE */
#if defined(CONFIG_6xx)
#ifdef CONFIG_6xx
ppc_md.power_save = ppc6xx_idle;
#endif
#ifdef CONFIG_POWER4
ppc_md.power_save = power4_idle;
#endif
platform_init(r3, r4, r5, r6, r7);
......
......@@ -577,6 +577,17 @@ TAUException(struct pt_regs *regs)
}
#endif /* CONFIG_INT_TAU */
#ifdef CONFIG_ALTIVEC
void
AltivecAssistException(struct pt_regs *regs)
{
if (regs->msr & MSR_VEC)
giveup_altivec(current);
/* XXX quick hack for now: set the non-Java bit in the VSCR */
current->thread.vscr.u[3] |= 0x10000;
}
#endif /* CONFIG_ALTIVEC */
void __init trap_init(void)
{
}
......@@ -4,6 +4,7 @@ config 4xx
default y
menu "IBM 4xx options"
depends on 4xx
choice
prompt "Machine Type"
......
......@@ -54,6 +54,9 @@
* vector that will be called by the ROM on wakeup
*/
_GLOBAL(low_sleep_handler)
#ifndef CONFIG_6xx
blr
#else
mflr r0
stw r0,4(r1)
stwu r1,-SL_SIZE(r1)
......@@ -381,4 +384,6 @@ turn_on_mmu:
sleep_storage:
.long 0
.balign L1_CACHE_LINE_SIZE, 0
#endif /* CONFIG_6xx */
.section .text
......@@ -434,9 +434,14 @@ setup_disp_fake_bi(ihandle dp)
if (strcmp(name, "valkyrie") == 0)
address += 0x1000;
#ifdef CONFIG_POWER4
extern int boot_text_mapped;
btext_setup_display(width, height, depth, pitch, address);
boot_text_mapped = 0;
#else
btext_setup_display(width, height, depth, pitch, address);
btext_prepare_BAT();
#endif
#endif /* CONFIG_BOOTX_TEXT */
}
......@@ -644,6 +649,72 @@ prom_hold_cpus(unsigned long mem)
}
}
#ifdef CONFIG_POWER4
/*
* Set up a hash table with a set of entries in it to map the
* first 64MB of RAM. This is used on 64-bit machines since
* some of them don't have BATs.
* We assume the PTE will fit in the primary PTEG.
*/
static inline void make_pte(unsigned long htab, unsigned int hsize,
unsigned int va, unsigned int pa, int mode)
{
unsigned int *pteg;
unsigned int hash, i, vsid;
vsid = ((va >> 28) * 0x111) << 12;
hash = ((va ^ vsid) >> 5) & 0x7fff80;
pteg = (unsigned int *)(htab + (hash & (hsize - 1)));
for (i = 0; i < 8; ++i, pteg += 4) {
if ((pteg[1] & 1) == 0) {
pteg[1] = vsid | ((va >> 16) & 0xf80) | 1;
pteg[3] = pa | mode;
break;
}
}
}
extern unsigned long _SDR1;
extern PTE *Hash;
extern unsigned long Hash_size;
static void __init
prom_alloc_htab(void)
{
unsigned int hsize;
unsigned long htab;
unsigned int addr;
/*
* Because of OF bugs we can't use the "claim" client
* interface to allocate memory for the hash table.
* This code is only used on 64-bit PPCs, and the only
* 64-bit PPCs at the moment are RS/6000s, and their
* OF is based at 0xc00000 (the 12M point), so we just
* arbitrarily use the 0x800000 - 0xc00000 region for the
* hash table.
* -- paulus.
*/
hsize = 4 << 20; /* POWER4 has no BATs */
htab = (8 << 20);
call_prom("claim", 3, 1, htab, hsize, 0);
Hash = (void *)(htab + KERNELBASE);
Hash_size = hsize;
_SDR1 = htab + __ilog2(hsize) - 18;
/*
* Put in PTEs for the first 64MB of RAM
*/
cacheable_memzero((void *)htab, hsize);
for (addr = 0; addr < 0x4000000; addr += 0x1000)
make_pte(htab, hsize, addr + KERNELBASE, addr,
_PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX);
make_pte(htab, hsize, 0x80013000, 0x80013000,
_PAGE_ACCESSED | _PAGE_NO_CACHE | _PAGE_GUARDED | PP_RWXX);
}
#endif /* CONFIG_POWER4 */
static void __init
prom_instantiate_rtas(void)
{
......@@ -745,6 +816,13 @@ prom_init(int r3, int r4, prom_entry pp)
prom_instantiate_rtas();
#ifdef CONFIG_POWER4
/*
* Find out how much memory we have and allocate a
* suitably-sized hash table.
*/
prom_alloc_htab();
#endif
mem = check_display(mem);
prom_print("copying OF device tree...");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment