[SPARC64]: Kill PROM locked TLB entry preservation code.
It is totally unnecessary complexity. After we take over the trap table, we handle all PROM tlb misses fully. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
6b6d017235
Коммит
3487d1d441
|
@ -116,14 +116,10 @@ static void smp_setup_percpu_timer(void);
|
|||
|
||||
static volatile unsigned long callin_flag = 0;
|
||||
|
||||
extern void inherit_locked_prom_mappings(int save_p);
|
||||
|
||||
void __init smp_callin(void)
|
||||
{
|
||||
int cpuid = hard_smp_processor_id();
|
||||
|
||||
inherit_locked_prom_mappings(0);
|
||||
|
||||
__local_per_cpu_offset = __per_cpu_offset(cpuid);
|
||||
|
||||
__flush_tlb_all();
|
||||
|
|
|
@ -178,13 +178,6 @@ __tsb_context_switch:
|
|||
brz %o2, 9f
|
||||
nop
|
||||
|
||||
/* We use entry 61 for this locked entry. This is the spitfire
|
||||
* TLB entry number, and luckily cheetah masks the value with
|
||||
* 15 ending us up with entry 13 which is what we want in that
|
||||
* case too.
|
||||
*
|
||||
* XXX Interactions with prom_world()...
|
||||
*/
|
||||
sethi %hi(sparc64_highest_unlocked_tlb_ent), %o4
|
||||
mov TLB_TAG_ACCESS, %g1
|
||||
lduw [%o4 + %lo(sparc64_highest_unlocked_tlb_ent)], %g2
|
||||
|
|
|
@ -555,294 +555,12 @@ static void __init inherit_prom_mappings(void)
|
|||
prom_printf("done.\n");
|
||||
}
|
||||
|
||||
static int prom_ditlb_set;
|
||||
struct prom_tlb_entry {
|
||||
int tlb_ent;
|
||||
unsigned long tlb_tag;
|
||||
unsigned long tlb_data;
|
||||
};
|
||||
struct prom_tlb_entry prom_itlb[16], prom_dtlb[16];
|
||||
|
||||
void prom_world(int enter)
|
||||
{
|
||||
unsigned long pstate;
|
||||
int i;
|
||||
|
||||
if (!enter)
|
||||
set_fs((mm_segment_t) { get_thread_current_ds() });
|
||||
|
||||
if (!prom_ditlb_set)
|
||||
return;
|
||||
|
||||
/* Make sure the following runs atomically. */
|
||||
__asm__ __volatile__("flushw\n\t"
|
||||
"rdpr %%pstate, %0\n\t"
|
||||
"wrpr %0, %1, %%pstate"
|
||||
: "=r" (pstate)
|
||||
: "i" (PSTATE_IE));
|
||||
|
||||
if (enter) {
|
||||
/* Install PROM world. */
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (prom_dtlb[i].tlb_ent != -1) {
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
|
||||
"i" (ASI_DMMU));
|
||||
if (tlb_type == spitfire)
|
||||
spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,
|
||||
prom_dtlb[i].tlb_data);
|
||||
else if (tlb_type == cheetah || tlb_type == cheetah_plus)
|
||||
cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent,
|
||||
prom_dtlb[i].tlb_data);
|
||||
}
|
||||
if (prom_itlb[i].tlb_ent != -1) {
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (prom_itlb[i].tlb_tag),
|
||||
"r" (TLB_TAG_ACCESS),
|
||||
"i" (ASI_IMMU));
|
||||
if (tlb_type == spitfire)
|
||||
spitfire_put_itlb_data(prom_itlb[i].tlb_ent,
|
||||
prom_itlb[i].tlb_data);
|
||||
else if (tlb_type == cheetah || tlb_type == cheetah_plus)
|
||||
cheetah_put_litlb_data(prom_itlb[i].tlb_ent,
|
||||
prom_itlb[i].tlb_data);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (prom_dtlb[i].tlb_ent != -1) {
|
||||
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
|
||||
if (tlb_type == spitfire)
|
||||
spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, 0x0UL);
|
||||
else
|
||||
cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent, 0x0UL);
|
||||
}
|
||||
if (prom_itlb[i].tlb_ent != -1) {
|
||||
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (TLB_TAG_ACCESS),
|
||||
"i" (ASI_IMMU));
|
||||
if (tlb_type == spitfire)
|
||||
spitfire_put_itlb_data(prom_itlb[i].tlb_ent, 0x0UL);
|
||||
else
|
||||
cheetah_put_litlb_data(prom_itlb[i].tlb_ent, 0x0UL);
|
||||
}
|
||||
}
|
||||
}
|
||||
__asm__ __volatile__("wrpr %0, 0, %%pstate"
|
||||
: : "r" (pstate));
|
||||
}
|
||||
|
||||
void inherit_locked_prom_mappings(int save_p)
|
||||
{
|
||||
int i;
|
||||
int dtlb_seen = 0;
|
||||
int itlb_seen = 0;
|
||||
|
||||
/* Fucking losing PROM has more mappings in the TLB, but
|
||||
* it (conveniently) fails to mention any of these in the
|
||||
* translations property. The only ones that matter are
|
||||
* the locked PROM tlb entries, so we impose the following
|
||||
* irrecovable rule on the PROM, it is allowed 8 locked
|
||||
* entries in the ITLB and 8 in the DTLB.
|
||||
*
|
||||
* Supposedly the upper 16GB of the address space is
|
||||
* reserved for OBP, BUT I WISH THIS WAS DOCUMENTED
|
||||
* SOMEWHERE!!!!!!!!!!!!!!!!! Furthermore the entire interface
|
||||
* used between the client program and the firmware on sun5
|
||||
* systems to coordinate mmu mappings is also COMPLETELY
|
||||
* UNDOCUMENTED!!!!!! Thanks S(t)un!
|
||||
*/
|
||||
if (save_p) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
prom_itlb[i].tlb_ent = -1;
|
||||
prom_dtlb[i].tlb_ent = -1;
|
||||
}
|
||||
}
|
||||
if (tlb_type == spitfire) {
|
||||
int high = sparc64_highest_unlocked_tlb_ent;
|
||||
for (i = 0; i <= high; i++) {
|
||||
unsigned long data;
|
||||
|
||||
/* Spitfire Errata #32 workaround */
|
||||
/* NOTE: Always runs on spitfire, so no cheetah+
|
||||
* page size encodings.
|
||||
*/
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"flush %%g6"
|
||||
: /* No outputs */
|
||||
: "r" (0),
|
||||
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
|
||||
|
||||
data = spitfire_get_dtlb_data(i);
|
||||
if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
|
||||
unsigned long tag;
|
||||
|
||||
/* Spitfire Errata #32 workaround */
|
||||
/* NOTE: Always runs on spitfire, so no
|
||||
* cheetah+ page size encodings.
|
||||
*/
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"flush %%g6"
|
||||
: /* No outputs */
|
||||
: "r" (0),
|
||||
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
|
||||
|
||||
tag = spitfire_get_dtlb_tag(i);
|
||||
if (save_p) {
|
||||
prom_dtlb[dtlb_seen].tlb_ent = i;
|
||||
prom_dtlb[dtlb_seen].tlb_tag = tag;
|
||||
prom_dtlb[dtlb_seen].tlb_data = data;
|
||||
}
|
||||
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
|
||||
spitfire_put_dtlb_data(i, 0x0UL);
|
||||
|
||||
dtlb_seen++;
|
||||
if (dtlb_seen > 15)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < high; i++) {
|
||||
unsigned long data;
|
||||
|
||||
/* Spitfire Errata #32 workaround */
|
||||
/* NOTE: Always runs on spitfire, so no
|
||||
* cheetah+ page size encodings.
|
||||
*/
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"flush %%g6"
|
||||
: /* No outputs */
|
||||
: "r" (0),
|
||||
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
|
||||
|
||||
data = spitfire_get_itlb_data(i);
|
||||
if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
|
||||
unsigned long tag;
|
||||
|
||||
/* Spitfire Errata #32 workaround */
|
||||
/* NOTE: Always runs on spitfire, so no
|
||||
* cheetah+ page size encodings.
|
||||
*/
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"flush %%g6"
|
||||
: /* No outputs */
|
||||
: "r" (0),
|
||||
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
|
||||
|
||||
tag = spitfire_get_itlb_tag(i);
|
||||
if (save_p) {
|
||||
prom_itlb[itlb_seen].tlb_ent = i;
|
||||
prom_itlb[itlb_seen].tlb_tag = tag;
|
||||
prom_itlb[itlb_seen].tlb_data = data;
|
||||
}
|
||||
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
|
||||
spitfire_put_itlb_data(i, 0x0UL);
|
||||
|
||||
itlb_seen++;
|
||||
if (itlb_seen > 15)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (tlb_type == cheetah || tlb_type == cheetah_plus) {
|
||||
int high = sparc64_highest_unlocked_tlb_ent;
|
||||
|
||||
for (i = 0; i <= high; i++) {
|
||||
unsigned long data;
|
||||
|
||||
data = cheetah_get_ldtlb_data(i);
|
||||
if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
|
||||
unsigned long tag;
|
||||
|
||||
tag = cheetah_get_ldtlb_tag(i);
|
||||
if (save_p) {
|
||||
prom_dtlb[dtlb_seen].tlb_ent = i;
|
||||
prom_dtlb[dtlb_seen].tlb_tag = tag;
|
||||
prom_dtlb[dtlb_seen].tlb_data = data;
|
||||
}
|
||||
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
|
||||
cheetah_put_ldtlb_data(i, 0x0UL);
|
||||
|
||||
dtlb_seen++;
|
||||
if (dtlb_seen > 15)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < high; i++) {
|
||||
unsigned long data;
|
||||
|
||||
data = cheetah_get_litlb_data(i);
|
||||
if ((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
|
||||
unsigned long tag;
|
||||
|
||||
tag = cheetah_get_litlb_tag(i);
|
||||
if (save_p) {
|
||||
prom_itlb[itlb_seen].tlb_ent = i;
|
||||
prom_itlb[itlb_seen].tlb_tag = tag;
|
||||
prom_itlb[itlb_seen].tlb_data = data;
|
||||
}
|
||||
__asm__ __volatile__("stxa %%g0, [%0] %1\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
|
||||
cheetah_put_litlb_data(i, 0x0UL);
|
||||
|
||||
itlb_seen++;
|
||||
if (itlb_seen > 15)
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Implement me :-) */
|
||||
BUG();
|
||||
}
|
||||
if (save_p)
|
||||
prom_ditlb_set = 1;
|
||||
}
|
||||
|
||||
/* Give PROM back his world, done during reboots... */
|
||||
void prom_reload_locked(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (prom_dtlb[i].tlb_ent != -1) {
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
|
||||
"i" (ASI_DMMU));
|
||||
if (tlb_type == spitfire)
|
||||
spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,
|
||||
prom_dtlb[i].tlb_data);
|
||||
else if (tlb_type == cheetah || tlb_type == cheetah_plus)
|
||||
cheetah_put_ldtlb_data(prom_dtlb[i].tlb_ent,
|
||||
prom_dtlb[i].tlb_data);
|
||||
}
|
||||
|
||||
if (prom_itlb[i].tlb_ent != -1) {
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"membar #Sync"
|
||||
: : "r" (prom_itlb[i].tlb_tag),
|
||||
"r" (TLB_TAG_ACCESS),
|
||||
"i" (ASI_IMMU));
|
||||
if (tlb_type == spitfire)
|
||||
spitfire_put_itlb_data(prom_itlb[i].tlb_ent,
|
||||
prom_itlb[i].tlb_data);
|
||||
else
|
||||
cheetah_put_litlb_data(prom_itlb[i].tlb_ent,
|
||||
prom_itlb[i].tlb_data);
|
||||
}
|
||||
}
|
||||
__asm__ __volatile__("flushw");
|
||||
}
|
||||
|
||||
#ifdef DCACHE_ALIASING_POSSIBLE
|
||||
|
@ -1066,6 +784,15 @@ void sparc_ultra_dump_dtlb(void)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void spitfire_errata32(void)
|
||||
{
|
||||
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
|
||||
"flush %%g6"
|
||||
: /* No outputs */
|
||||
: "r" (0),
|
||||
"r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
|
||||
}
|
||||
|
||||
extern unsigned long cmdline_memory_size;
|
||||
|
||||
unsigned long __init bootmem_init(unsigned long *pages_avail)
|
||||
|
@ -1375,8 +1102,6 @@ void __init paging_init(void)
|
|||
setup_tba(this_is_starfire);
|
||||
}
|
||||
|
||||
inherit_locked_prom_mappings(1);
|
||||
|
||||
__flush_tlb_all();
|
||||
|
||||
/* Setup bootmem... */
|
||||
|
|
Загрузка…
Ссылка в новой задаче