* [Qemu-devel] [PATCH] PMAC NVRAM cleanup
@ 2008-05-01 11:41 Laurent Vivier
2008-05-01 14:49 ` Blue Swirl
2008-08-24 19:20 ` Andreas Färber
0 siblings, 2 replies; 4+ messages in thread
From: Laurent Vivier @ 2008-05-01 11:41 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 372 bytes --]
Hi,
I'm trying to boot openbios on PPC target (for the moment I'm only
able to load yaboot).
This patch is a cleanup of PMAC nvram.
It stores nvram in a file and create valid partitions.
This doesn't break OpenHackware.
Regards,
Laurent
----------------------- Laurent Vivier ----------------------
"The best way to predict the future is to invent it."
- Alan Kay
[-- Attachment #2: 0001-PowerMac-NVRAM-cleanup.patch --]
[-- Type: application/octet-stream, Size: 8135 bytes --]
From 545b62d971c549155a03b6540536069ad9f9bcca Mon Sep 17 00:00:00 2001
From: Laurent Vivier <Laurent@lvivier.info>
Date: Thu, 1 May 2008 12:25:18 +0200
Subject: [PATCH] PowerMac NVRAM cleanup
---
hw/mac_nvram.c | 151 ++++++++++++++++++++++++++++++++++++++++++++--------
hw/ppc_mac.h | 4 +-
hw/ppc_oldworld.c | 4 +-
3 files changed, 131 insertions(+), 28 deletions(-)
diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index 7304ac2..366cd62 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -25,11 +25,25 @@
#include "hw.h"
#include "ppc_mac.h"
+#define DEF_SYSTEM_SIZE 0xc10
+
+#define NV_SIG_SYSTEM 0x70
+#define NV_SIG_FREE 0x7f
+
+#define NV_NAME_LEN 12
+
+#define NV_SIGNATURE 0
+#define NV_CHECKSUM 1
+#define NV_LEN 2
+#define NV_NAME 4
+#define NV_DATA 16
+
struct MacIONVRAMState {
target_phys_addr_t mem_base;
- target_phys_addr_t size;
+ uint32_t size;
+ QEMUFile *file;
int mem_index;
- uint8_t data[0x2000];
+ uint8_t data[NVRAM_SIZE];
};
/* Direct access to NVRAM */
@@ -39,7 +53,7 @@ uint32_t macio_nvram_read (void *opaque, uint32_t addr)
uint32_t ret;
// printf("%s: %p addr %04x\n", __func__, s, addr);
- if (addr < 0x2000)
+ if (addr < NVRAM_SIZE)
ret = s->data[addr];
else
ret = -1;
@@ -52,7 +66,7 @@ void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
MacIONVRAMState *s = opaque;
// printf("%s: %p addr %04x val %02x\n", __func__, s, addr, val);
- if (addr < 0x2000)
+ if (addr < NVRAM_SIZE)
s->data[addr] = val;
}
@@ -63,9 +77,14 @@ static void macio_nvram_writeb (void *opaque,
MacIONVRAMState *s = opaque;
addr -= s->mem_base;
- addr = (addr >> 4) & 0x1fff;
+ addr = (addr >> 4) & (NVRAM_SIZE-1);
s->data[addr] = value;
// printf("macio_nvram_writeb %04x = %02x\n", addr, value);
+ if (s->file) {
+ qemu_fseek(s->file, addr, SEEK_SET);
+ qemu_put_byte(s->file, value);
+ qemu_fflush(s->file);
+ }
}
static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
@@ -74,7 +93,7 @@ static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
uint32_t value;
addr -= s->mem_base;
- addr = (addr >> 4) & 0x1fff;
+ addr = (addr >> 4) & (NVRAM_SIZE-1);
value = s->data[addr];
// printf("macio_nvram_readb %04x = %02x\n", addr, value);
@@ -93,17 +112,32 @@ static CPUReadMemoryFunc *nvram_read[] = {
&macio_nvram_readb,
};
-MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size)
+MacIONVRAMState *macio_nvram_init (int *mem_index, const char *filename)
{
MacIONVRAMState *s;
+ QEMUFile *file;
s = qemu_mallocz(sizeof(MacIONVRAMState));
if (!s)
return NULL;
- s->size = size;
+ s->size = NVRAM_SIZE << 4;
s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
*mem_index = s->mem_index;
+ /* Read current file */
+ file = qemu_fopen(filename, "rb");
+ if (file) {
+ /* Read nvram contents */
+ qemu_get_buffer(file, s->data, s->size >> 4);
+ qemu_fclose(file);
+ }
+ s->file = qemu_fopen(filename, "wb");
+ if (s->file) {
+ /* Write back contents, as 'wb' mode cleaned the file */
+ qemu_put_buffer(s->file, s->data, s->size >> 4);
+ qemu_fflush(s->file);
+ }
+
return s;
}
@@ -116,26 +150,95 @@ void macio_nvram_map (void *opaque, target_phys_addr_t mem_base)
cpu_register_physical_memory(mem_base, s->size, s->mem_index);
}
-static uint8_t nvram_chksum (const uint8_t *buf, int n)
+static uint8_t nvram_chksum (const uint8_t *buf)
{
int sum, i;
- sum = 0;
- for(i = 0; i < n; i++)
+ sum = buf[0];
+ for(i = 2; i < 16; i++) {
sum += buf[i];
- return (sum & 0xff) + (sum >> 8);
+ if (sum > 255)
+ sum = (sum - 256 + 1) & 0xff;
+ }
+ return sum;
+}
+
+static inline uint16_t nvram_readw(uint8_t *addr)
+{
+ return ((*addr) << 8) + *(addr + 1);
+}
+
+static inline void nvram_writew(uint8_t *addr, uint16_t val)
+{
+ *addr = val >> 8;
+ *(addr + 1) = val;
+}
+
+static void nvram_set_header(MacIONVRAMState *nvr,
+ uint32_t addr,
+ uint8_t signature,
+ uint16_t size,
+ char* name)
+{
+ uint8_t *buf = nvr->data;
+
+ memset(buf + addr, 0, NV_DATA);
+ buf[addr + NV_SIGNATURE] = signature;
+ strncpy(buf + addr + NV_NAME, name, NV_NAME_LEN);
+ nvram_writew(buf + addr + NV_LEN, size >> 4);
+ buf[addr + NV_CHECKSUM] = nvram_chksum(buf + addr);
+}
+
+static void create_free_part(MacIONVRAMState *nvr, uint32_t addr, int size )
+{
+ nvram_set_header(nvr, addr, NV_SIG_FREE, size, "777777777777");
+}
+
+static int
+next_nvpart(MacIONVRAMState *nvr, uint32_t *addr, uint32_t end)
+{
+ uint8_t *buf = nvr->data;
+ int len;
+
+ len = nvram_readw(buf + *addr + NV_LEN);
+ if (len == 0)
+ return 1;
+
+ *addr = (*addr) + len;
+ if( *addr < end )
+ return 1;
+ if( *addr == end )
+ return 0;
+ return -1;
+}
+
+static int create_nv_part(MacIONVRAMState *nvr, uint32_t base, int max_size,
+ int signature, char *name, int size )
+{
+ uint8_t *buf = nvr->data;
+ uint32_t addr = base;
+ uint32_t end = base + max_size;
+ int len;
+
+ do {
+ if (buf[addr + NV_SIGNATURE] != NV_SIG_FREE)
+ continue;
+
+ len = nvram_readw(buf + addr + NV_LEN) << 4;
+ if (len < size)
+ size = len;
+
+ nvram_set_header(nvr, addr, signature, size, name);
+ if (len > size)
+ create_free_part(nvr, addr + size, len - size);
+ return size;
+ } while (next_nvpart(nvr, &addr, end) > 0 );
+ return -1;
}
-/* set a free Mac OS NVRAM partition */
-void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len)
+/* set a system Mac OS NVRAM partition */
+void pmac_format_nvram_partition (MacIONVRAMState *nvr)
{
- uint8_t *buf;
- char partition_name[12] = "wwwwwwwwwwww";
-
- buf = nvr->data;
- buf[0] = 0x7f; /* free partition magic */
- buf[1] = 0; /* checksum */
- buf[2] = len >> 8;
- buf[3] = len;
- memcpy(buf + 4, partition_name, 12);
- buf[1] = nvram_chksum(buf, 16);
+ create_free_part(nvr, 0, sizeof(nvr->data));
+ create_nv_part(nvr, 0, sizeof(nvr->data),
+ NV_SIG_SYSTEM, "common", DEF_SYSTEM_SIZE);
}
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index 3a26cde..5dd727d 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -62,9 +62,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic);
/* Mac NVRAM */
typedef struct MacIONVRAMState MacIONVRAMState;
-MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size);
+MacIONVRAMState *macio_nvram_init (int *mem_index, const char *filename);
void macio_nvram_map (void *opaque, target_phys_addr_t mem_base);
-void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
+void pmac_format_nvram_partition (MacIONVRAMState *nvr);
uint32_t macio_nvram_read (void *opaque, uint32_t addr);
void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 6b4f202..41f1128 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -334,8 +334,8 @@ static void ppc_heathrow_init (int ram_size, int vga_ram_size,
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
- nvr = macio_nvram_init(&nvram_mem_index, 0x2000);
- pmac_format_nvram_partition(nvr, 0x2000);
+ nvr = macio_nvram_init(&nvram_mem_index, "g3bw_nvram");
+ pmac_format_nvram_partition(nvr);
dbdma_init(&dbdma_mem_index);
--
1.5.5
[-- Attachment #3: Type: text/plain, Size: 3 bytes --]
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] PMAC NVRAM cleanup
2008-05-01 11:41 [Qemu-devel] [PATCH] PMAC NVRAM cleanup Laurent Vivier
@ 2008-05-01 14:49 ` Blue Swirl
2008-05-01 15:56 ` Laurent Vivier
2008-08-24 19:20 ` Andreas Färber
1 sibling, 1 reply; 4+ messages in thread
From: Blue Swirl @ 2008-05-01 14:49 UTC (permalink / raw)
To: qemu-devel
On 5/1/08, Laurent Vivier <Laurent@lvivier.info> wrote:
> Hi,
>
> I'm trying to boot openbios on PPC target (for the moment I'm only able to
> load yaboot).
Great! Which machine are you using? OpenBIOS has some support for
things called briq, mol and pearpc, are any of those useful?
> This patch is a cleanup of PMAC nvram.
>
> It stores nvram in a file and create valid partitions.
In no other machine nvram is loaded from a file. On Sparc most
configuration needs can be addressed by using -prom-env switch.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] PMAC NVRAM cleanup
2008-05-01 14:49 ` Blue Swirl
@ 2008-05-01 15:56 ` Laurent Vivier
0 siblings, 0 replies; 4+ messages in thread
From: Laurent Vivier @ 2008-05-01 15:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Blue Swirl
Le jeudi 01 mai 2008 à 17:49 +0300, Blue Swirl a écrit :
> On 5/1/08, Laurent Vivier <Laurent@lvivier.info> wrote:
> > Hi,
> >
> > I'm trying to boot openbios on PPC target (for the moment I'm only able to
> > load yaboot).
>
> Great! Which machine are you using? OpenBIOS has some support for
> things called briq, mol and pearpc, are any of those useful?
I'm working with files from pearpc.
> > This patch is a cleanup of PMAC nvram.
> >
> > It stores nvram in a file and create valid partitions.
>
> In no other machine nvram is loaded from a file. On Sparc most
> configuration needs can be addressed by using -prom-env switch.
In fact I took syntax and some parts from ds1225y which loads nvram from
a file.
I will improve this part (better default filename, switch to specify
filename and -prom-env management) later.
Thank you for your comments. I'm going to repost a patch based on
structures and functions found in hw/firmware_abi.h
Regards,
Laurent
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] PMAC NVRAM cleanup
2008-05-01 11:41 [Qemu-devel] [PATCH] PMAC NVRAM cleanup Laurent Vivier
2008-05-01 14:49 ` Blue Swirl
@ 2008-08-24 19:20 ` Andreas Färber
1 sibling, 0 replies; 4+ messages in thread
From: Andreas Färber @ 2008-08-24 19:20 UTC (permalink / raw)
To: qemu-devel, Laurent Vivier
Laurent,
Am 01.05.2008 um 13:41 schrieb Laurent Vivier:
> I'm trying to boot openbios on PPC target (for the moment I'm only
> able to load yaboot).
>
> This patch is a cleanup of PMAC nvram.
>
> It stores nvram in a file and create valid partitions.
>
> This doesn't break OpenHackware.
Did you make any progress booting OpenBIOS/ppc? It seems your v2 did
not get committed?
Blue Swirl once said the problem with the PearPC OpenBIOS was that it
builds an ELF file that is unsuitable for QEMU, is that why you
mention yaboot? Or did you find a way for OpenBIOS to actually execute
and run yaboot?
Regards,
Andreas
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-08-24 19:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-01 11:41 [Qemu-devel] [PATCH] PMAC NVRAM cleanup Laurent Vivier
2008-05-01 14:49 ` Blue Swirl
2008-05-01 15:56 ` Laurent Vivier
2008-08-24 19:20 ` Andreas Färber
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).