qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Enable support for PPC64 on qemu target v2
@ 2009-02-26 23:39 Alexander Graf
  2009-02-27  0:25 ` Laurent Vivier
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Alexander Graf @ 2009-02-26 23:39 UTC (permalink / raw)
  To: openbios; +Cc: qemu-devel, Laurent Vivier

[-- Attachment #1: Type: text/plain, Size: 466 bytes --]

This patch enables OpenBIOS to initialize on PPC64, enabling support  
for -cpu 970fx.
It gets up to the boot prompt and works rather good so far, though I  
haven't been able to run a kernel yet.

For more recent PowerPC CPUs the PTE layout has changed, so we need to  
take that into account and create PTEs according to the new layout and  
at the new physical positions.

v2 takes Laurent's comments into account

Signed-off-by: Alexander Graf <alex@csgraf.de>


[-- Attachment #2.1: Type: text/html, Size: 683 bytes --]

[-- Attachment #2.2: ppc64.patch --]
[-- Type: application/octet-stream, Size: 6194 bytes --]

Index: include/ofmem.h
===================================================================
--- include/ofmem.h	(revision 459)
+++ include/ofmem.h	(working copy)
@@ -30,6 +30,8 @@
 extern ulong 	ofmem_translate( ulong virt, int *ret_mode );
 
 #ifdef CONFIG_PPC
+#define PAGE_SHIFT   12
+
 ulong get_ram_size( void );
 ulong get_ram_top( void );
 ulong get_ram_bottom( void );
@@ -39,9 +41,6 @@
 void ofmem_register( phandle_t ph );
 #elif defined(CONFIG_SPARC32)
 #define PAGE_SHIFT   12
-#define PAGE_SIZE    (1 << PAGE_SHIFT)
-#define PAGE_MASK    (~(PAGE_SIZE - 1))
-#define PAGE_ALIGN(addr)  (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
 
 /* arch/sparc32/lib.c */
 struct mem;
@@ -53,4 +52,10 @@
 void *map_io(uint64_t pa, int size);
 #endif
 
+#ifdef PAGE_SHIFT
+#define PAGE_SIZE    (1 << PAGE_SHIFT)
+#define PAGE_MASK    (~(PAGE_SIZE - 1))
+#define PAGE_ALIGN(addr)  (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
+#endif
+
 #endif   /* _H_OFMEM */
Index: arch/ppc/qemu/init.c
===================================================================
--- arch/ppc/qemu/init.c	(revision 459)
+++ arch/ppc/qemu/init.c	(working copy)
@@ -238,6 +238,19 @@
     fword("finish-device");
 }
 
+static void
+cpu_970_init(const struct cpudef *cpu)
+{
+    cpu_generic_init(cpu);
+
+    PUSH(0);
+    fword("encode-int");
+    push_str("reg");
+    fword("property");
+
+    fword("finish-device");
+}
+
 static const struct cpudef ppc_defs[] = {
     {
         .iu_version = 0x00040000,
@@ -359,6 +372,18 @@
         .clock_frequency = 0x1dcd6500,
         .initfn = cpu_g4_init,
     },
+    { // XXX find out real values
+        .iu_version = 0x003C0000,
+        .name = "PowerPC,970FX",
+        .icache_size = 0x8000,
+        .dcache_size = 0x8000,
+        .icache_sets = 0x80,
+        .dcache_sets = 0x80,
+        .icache_block_size = 0x80,
+        .dcache_block_size = 0x80,
+        .clock_frequency = 0x1dcd6500,
+        .initfn = cpu_970_init,
+    },
 };
 
 static const struct cpudef *
Index: arch/ppc/qemu/ofmem.c
===================================================================
--- arch/ppc/qemu/ofmem.c	(revision 459)
+++ arch/ppc/qemu/ofmem.c	(working copy)
@@ -621,9 +621,75 @@
 }
 
 static void
-hash_page( ulong ea, ulong phys, int mode )
+hash_page_64( ulong ea, ulong phys, int mode )
 {
 	static int next_grab_slot=0;
+	uint64_t vsid_mask, page_mask, pgidx, hash;
+	uint64_t htab_mask, mask, avpn;
+	ulong pgaddr;
+	int i, found;
+	unsigned int vsid, vsid_sh, sdr, sdr_sh, sdr_mask;
+	mPTE_64_t *pp;
+
+	vsid = (ea>>28) + SEGR_BASE;
+	vsid_sh = 7;
+	vsid_mask = 0x00003FFFFFFFFF80ULL;
+	asm ( "mfsdr1 %0" : "=r" (sdr) );
+	sdr_sh = 18;
+	sdr_mask = 0x3FF80;
+	page_mask = 0x0FFFFFFF; // XXX correct?
+	pgidx = (ea & page_mask) >> PAGE_SHIFT;
+	avpn = (vsid << 12) | ((pgidx >> 4) & 0x0F80);;
+
+	hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
+	htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
+	mask = (htab_mask << sdr_sh) | sdr_mask;
+	pgaddr = sdr | (hash & mask);
+	pp = (mPTE_64_t *)pgaddr;
+
+	/* replace old translation */
+	for( found=0, i=0; !found && i<8; i++ )
+		if( pp[i].avpn == avpn )
+			found=1;
+
+	/* otherwise use a free slot */
+	for( i=0; !found && i<8; i++ )
+		if( !pp[i].v )
+			found=1;
+
+	/* out of slots, just evict one */
+	if( !found ) {
+		i = next_grab_slot + 1;
+		next_grab_slot = (next_grab_slot + 1) % 8;
+	}
+	i--;
+	{
+	mPTE_64_t p = {
+		// .avpn_low = avpn,
+		.avpn = avpn >> 7,
+		.h = 0,
+		.v = 1,
+
+		.rpn = (phys & ~0xfff) >> 12,
+		.r = mode & (1 << 8) ? 1 : 0,
+		.c = mode & (1 << 7) ? 1 : 0,
+		.w = mode & (1 << 6) ? 1 : 0,
+		.i = mode & (1 << 5) ? 1 : 0,
+		.m = mode & (1 << 4) ? 1 : 0,
+		.g = mode & (1 << 3) ? 1 : 0,
+		.n = mode & (1 << 2) ? 1 : 0,
+		.pp = mode & 3,
+	};
+	pp[i] = p;
+	}
+
+	asm volatile( "tlbie %0"  :: "r"(ea) );
+}
+
+static void
+hash_page_32( ulong ea, ulong phys, int mode )
+{
+	static int next_grab_slot=0;
 	ulong *upte, cmp, hash1;
 	int i, vsid, found;
 	mPTE_t *pp;
@@ -660,6 +726,22 @@
 	asm volatile( "tlbie %0"  :: "r"(ea) );
 }
 
+static int is_ppc64(void)
+{
+	unsigned int pvr;
+	asm volatile("mfspr %0, 0x11f" : "=r" (pvr) );
+
+	return ((pvr >= 0x330000) && (pvr < 0x70330000));
+}
+
+static void hash_page( ulong ea, ulong phys, int mode )
+{
+	if ( is_ppc64() )
+		hash_page_64(ea, phys, mode);
+	else
+		hash_page_32(ea, phys, mode);
+}
+
 void
 dsi_exception( void )
 {
@@ -699,6 +781,7 @@
 	ofmem_t *ofmem = OFMEM;
 	ulong sdr1, sr_base, msr;
 	ulong hash_base;
+	ulong hash_mask = 0xffff0000;
 	int i;
 
 	memset(ofmem, 0, sizeof(ofmem_t));
@@ -706,7 +789,10 @@
 
 	/* SDR1: Storage Description Register 1 */
 
-	hash_base = (ramsize - 0x00100000 - HASH_SIZE) & 0xffff0000;
+	if(is_ppc64())
+		hash_mask = 0xfff00000;
+
+	hash_base = (ramsize - 0x00100000 - HASH_SIZE) & hash_mask;
         memset((void *)hash_base, 0, HASH_SIZE);
 	sdr1 = hash_base | ((HASH_SIZE-1) >> 16);
 	asm volatile("mtsdr1 %0" :: "r" (sdr1) );
Index: arch/ppc/qemu/mmutypes.h
===================================================================
--- arch/ppc/qemu/mmutypes.h	(revision 459)
+++ arch/ppc/qemu/mmutypes.h	(working copy)
@@ -38,7 +38,28 @@
 	unsigned long pp:2;	/* Page protection */
 } mPTE_t;
 
+typedef struct mPTE_64 {
+	uint32_t avpn_low;	/* Abbreviated Virtual Page Number (unused) */
+	uint32_t avpn:25;	/* Abbreviated Virtual Page Number */
+	uint32_t sw:4;		/* Software Use */
+	uint32_t  :1;		/* Reserved */
+	uint32_t h:1;		/* Hash algorithm indicator */
+	uint32_t v:1;		/* Entry is valid */
 
+	uint32_t rpn_low;	/* Real (physical) page number (unused) */
+	uint32_t rpn:20;	/* Real (physical) page number */
+	uint32_t    :2;		/* Reserved */
+	uint32_t ac:1;		/* Address Compare*/
+	uint32_t r:1;		/* Referenced */
+	uint32_t c:1;		/* Changed */
+	uint32_t w:1;		/* Write-thru cache mode */
+	uint32_t i:1;		/* Cache inhibited */
+	uint32_t m:1;		/* Memory coherence */
+	uint32_t g:1;		/* Guarded */
+	uint32_t n:1;		/* No-Execute */
+	uint32_t pp:2;		/* Page protection */
+} mPTE_64_t;
+
 typedef struct _mBATU {		/* Upper part of BAT (all except 601) */
         unsigned long bepi:15;	/* Effective page index (virtual address) */
         unsigned long :4;	/* Unused */

[-- Attachment #2.3: Type: text/html, Size: 145 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2009-02-28  8:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-26 23:39 [Qemu-devel] [PATCH] Enable support for PPC64 on qemu target v2 Alexander Graf
2009-02-27  0:25 ` Laurent Vivier
2009-02-27 20:03 ` Blue Swirl
2009-02-27 21:47 ` Blue Swirl
2009-02-28  0:24   ` Alexander Graf
2009-02-28  8:17     ` Blue Swirl
2009-02-27 22:24 ` Laurent Vivier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).