summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbcollins <tailor@grayson>2006-06-01 13:19:51 -0400
committerBen Collins <bcollins@ubuntu.com>2006-06-01 13:19:51 -0400
commit494770a17eea7192d3242051e76f4da6d838e3a1 (patch)
treede0a6efdcfdcb81b3011c9ca9b55bee0b519482b
parenta9ea834b5079c32eaacb3c057161eab7db054c96 (diff)
downloadsilo-494770a17eea7192d3242051e76f4da6d838e3a1.tar.gz
[silo @ 167]
Subject: [PATCH]: SILO Niagara/SUN4V support From: "David S. Miller" <davem@davemloft.net> This patch against silo-1.4.10 makes SILO work on Niagara/SUN4V: 1) Don't try to access %ver register on Niagara, this will trap because it's a hyperprivileged operation on SUN4V. We detect SUN4V with an ugly trick, we try to write to the PSTATE_AG bit of %pstate. If it reads back zero, it is SUN4V. A better way to do this would be to fetch the "compatible" property of the OBP root node and check if it is "sun4v" but that might not be so easy to do this early. To be honest, the necessity of this I-cache flushing code itself is suspect. I bet we can delete the whole thing or replace it with a portable loop that does "flush %reg" over the area we want the be I-cache synced. 2) Kill all of this code flushing the fixed SUN4U TLB entries. We don't load the TLB entries by hand any more so this code is just noise and would be wrong on SUN4V in any event. 3) Kill all of the %tick{_cmpr} register poking. All this timer code cares about is that it records %tick when it starts, and then later make relative measurements using that saved value. The rest of the code touching %tick{_cmpr} is superfluous. Besides you can't write to %tick on SUN4V as that is a hyperprivileged operation. 4) Return 'sun4u' from silo_get_architecture() when we detect 'sun4v', we want to run the same code paths. We could add a "sun4v" architecture type but I see no gain from that as it would just bloat up all the sun4u tests with a new "||" branch. If someone could at least do some light testing of this on SUN4U I'd really appreciate this. Ben, please don't apply this until you or someone else does at least one SUN4U smoke test. I've successfully tested this on a T-200 with 16GB of ram. Thanks.#
-rw-r--r--Rules.make2
-rw-r--r--first-isofs/crt0.S19
-rw-r--r--second/crt0.S19
-rw-r--r--second/memory.c45
-rw-r--r--second/misc.c1
-rw-r--r--second/timer.c19
6 files changed, 40 insertions, 65 deletions
diff --git a/Rules.make b/Rules.make
index 08c2e20..1ac3a9d 100644
--- a/Rules.make
+++ b/Rules.make
@@ -3,7 +3,7 @@ IMGVERSION=0.99
RM=rm -f
# We want to force 32-bit builds
CC=gcc -m32
-LD=ld
+LD=ld -m elf32_sparc
AS=as
STRIP=strip
NM=nm
diff --git a/first-isofs/crt0.S b/first-isofs/crt0.S
index a8a340c..2db1281 100644
--- a/first-isofs/crt0.S
+++ b/first-isofs/crt0.S
@@ -112,6 +112,25 @@ flush_icache:
tst %i4 /* quit unless it's Sun4u */
be 0f
nop
+
+ /* Careful, we cannot read the %ver register on sun4v because
+ * there that register is hyperprivileged and we are executing
+ * in privileged mode.
+ *
+ * This early on it's difficult to portably detect sun4v as
+ * that requires OBP calls. So do this super-ugly trick of
+ * trying to set the PSTATE_AG bit in %pstate which will read
+ * back as zero on sun4u.
+ */
+ rdpr %pstate, %l0
+ or %l0, 0x1, %l1
+ wrpr %l1, %pstate
+ rdpr %pstate, %l1
+ wrpr %l0, %pstate
+ andcc %l1, 0x1, %g0
+ be,pn %xcc, 0f
+ nop
+
rdpr %ver, %l0
srlx %l0, (32 + 16), %l1
cmp %l1, 0x3e
diff --git a/second/crt0.S b/second/crt0.S
index a6d145e..f1ba1c8 100644
--- a/second/crt0.S
+++ b/second/crt0.S
@@ -183,6 +183,25 @@ flush_icache:
tst %i4 /* quit unless it's Sun4u */
be 0f
nop
+
+ /* Careful, we cannot read the %ver register on sun4v because
+ * there that register is hyperprivileged and we are executing
+ * in privileged mode.
+ *
+ * This early on it's difficult to portably detect sun4v as
+ * that requires OBP calls. So do this super-ugly trick of
+ * trying to set the PSTATE_AG bit in %pstate which will read
+ * back as zero on sun4u.
+ */
+ rdpr %pstate, %l0
+ or %l0, 0x1, %l1
+ wrpr %l1, %pstate
+ rdpr %pstate, %l1
+ wrpr %l0, %pstate
+ andcc %l1, 0x1, %g0
+ be,pn %xcc, 0f
+ nop
+
rdpr %ver, %l0
srlx %l0, (32 + 16), %l1
cmp %l1, 0x3e
diff --git a/second/memory.c b/second/memory.c
index 9d6f350..dace2de 100644
--- a/second/memory.c
+++ b/second/memory.c
@@ -21,9 +21,6 @@
#include <silo.h>
-#define IMAGE_TLB_ENTRY 61
-#define INITRD_TLB_ENTRY 60
-
#define INITRD_VIRT_ADDR 0x40c00000
#define IMAGE_VIRT_ADDR 0x40000000
@@ -198,20 +195,6 @@ inline void sun4m_set_direct (unsigned long l, unsigned long set)
"sta %0, [%1] 32\n\t" : : "r" (set), "r" (l));
}
-#ifndef TLB_TAG_ACCESS
-#define TLB_TAG_ACCESS 0x30
-#endif
-
-#ifndef ASI_DMMU
-#define ASI_DMMU 0x58
-#define ASI_DTLB_DATA_ACCESS 0x5d
-#endif
-
-#ifndef ASI_IMMU
-#define ASI_IMMU 0x50
-#define ASI_ITLB_DATA_ACCESS 0x55
-#endif
-
unsigned long long initrd_phys;
unsigned long sun4m_initrd_pa;
@@ -300,7 +283,6 @@ static char *sun4u_memory_find (unsigned int len, int is_kernel)
unsigned long long size;
} *p = (struct p1275_mem *)0;
unsigned int virt = (is_kernel ? IMAGE_VIRT_ADDR : INITRD_VIRT_ADDR);
- unsigned int tlb_entry = (is_kernel ? IMAGE_TLB_ENTRY : INITRD_TLB_ENTRY);
unsigned long long phys = 0, phys_base;
p = (struct p1275_mem *)malloc(2048);
@@ -390,7 +372,6 @@ static char *sun4u_memory_find (unsigned int len, int is_kernel)
static void sun4u_memory_release(int is_kernel)
{
unsigned long long virt, len;
- unsigned int tlb_entry = (is_kernel ? IMAGE_TLB_ENTRY : INITRD_TLB_ENTRY);
if (is_kernel) {
virt = sun4u_image_virt;
@@ -406,32 +387,6 @@ static void sun4u_memory_release(int is_kernel)
prom_unmap(len, virt);
- __asm __volatile("\n\
- rdpr %%pil, %%g1\n\
- wrpr 15, %%pil\n\
- stxa %%g0, [%0] %1\n\
- membar #Sync\n\
- stxa %%g0, [%2] %3\n\
- membar #Sync\n\
- wrpr %%g1, %%pil\n\
- " : : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU),
- "r" (tlb_entry << 3),
- "i" (ASI_DTLB_DATA_ACCESS) : "g1");
-
- if (is_kernel) {
- __asm __volatile("\n\
- rdpr %%pil, %%g1\n\
- wrpr 15, %%pil\n\
- stxa %%g0, [%0] %1\n\
- membar #Sync\n\
- stxa %%g0, [%2] %3\n\
- membar #Sync\n\
- wrpr %%g1, %%pil\n\
- " : : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU),
- "r" (tlb_entry << 3),
- "i" (ASI_ITLB_DATA_ACCESS) : "g1");
- }
-
if (is_kernel)
sun4u_image_len = 0;
else
diff --git a/second/misc.c b/second/misc.c
index 1fb9527..f0ea6a3 100644
--- a/second/misc.c
+++ b/second/misc.c
@@ -518,6 +518,7 @@ enum arch silo_get_architecture(void)
case 'e':
return sun4e;
case 'u':
+ case 'v':
return sun4u;
default:
for(i = 0; i < NUM_SUN_MACHINES; i++)
diff --git a/second/timer.c b/second/timer.c
index 839c71c..892d439 100644
--- a/second/timer.c
+++ b/second/timer.c
@@ -40,8 +40,6 @@ static volatile struct sun4m_timer_regs *sun4m_timer;
static volatile struct sun4c_timer_info *sun4c_timer;
static unsigned char *addr_to_free = 0;
static int len_to_free;
-static unsigned long long sun4u_tickcmpr;
-static int sun4u_notimer = 0;
static struct mostek48t02 *mregs;
static long clock_frequency;
@@ -156,16 +154,6 @@ static inline int sun4u_init_timer ()
}
if (!foundcpu || !clock_frequency)
clock_frequency = prom_getint(prom_root_node, "clock-frequency") / 100;
- if (notimer) {
- sun4u_notimer = 1;
- __asm__ __volatile__ ("\t"
- "rd %%tick_cmpr, %%g1\n\t"
- "stx %%g1, [%0]\n\t"
- "mov 1, %%g1\n\t"
- "sllx %%g1, 63, %%g1\n\t"
- "wr %%g1, 0, %%tick_cmpr"
- : : "r" (&sun4u_tickcmpr) : "g1");
- }
return 0;
}
@@ -206,13 +194,6 @@ int init_timer ()
void close_timer ()
{
- if (sun4u_notimer) {
- __asm__ __volatile__("\t"
- "ldx [%0], %%g1\n\t"
- "wrpr %%g0, 0, %%tick\n\t"
- "wr %%g1, 0, %%tick_cmpr"
- : : "r" (&sun4u_tickcmpr) : "g1");
- }
if (addr_to_free) {
if (addr_to_free == (unsigned char *)0xffffffff)
sun4c_unmapio (TICKER_VIRTUAL);