|
|
1.1 root 1: /*
2: * PowerMac NVRAM emulation
3: *
4: * Copyright (c) 2005-2007 Fabrice Bellard
5: * Copyright (c) 2007 Jocelyn Mayer
6: *
7: * Permission is hereby granted, free of charge, to any person obtaining a copy
8: * of this software and associated documentation files (the "Software"), to deal
9: * in the Software without restriction, including without limitation the rights
10: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11: * copies of the Software, and to permit persons to whom the Software is
12: * furnished to do so, subject to the following conditions:
13: *
14: * The above copyright notice and this permission notice shall be included in
15: * all copies or substantial portions of the Software.
16: *
17: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23: * THE SOFTWARE.
24: */
25: #include "hw.h"
1.1.1.2 root 26: #include "firmware_abi.h"
27: #include "sysemu.h"
1.1 root 28: #include "ppc_mac.h"
29:
1.1.1.2 root 30: /* debug NVR */
31: //#define DEBUG_NVR
32:
33: #ifdef DEBUG_NVR
1.1.1.3 root 34: #define NVR_DPRINTF(fmt, ...) \
35: do { printf("NVR: " fmt , ## __VA_ARGS__); } while (0)
1.1.1.2 root 36: #else
1.1.1.3 root 37: #define NVR_DPRINTF(fmt, ...)
1.1.1.2 root 38: #endif
39:
1.1 root 40: struct MacIONVRAMState {
1.1.1.7 root 41: uint32_t size;
1.1.1.8 ! root 42: MemoryRegion mem;
1.1.1.2 root 43: unsigned int it_shift;
44: uint8_t *data;
1.1 root 45: };
46:
1.1.1.2 root 47: #define DEF_SYSTEM_SIZE 0xc10
48:
1.1 root 49: /* Direct access to NVRAM */
50: uint32_t macio_nvram_read (void *opaque, uint32_t addr)
51: {
52: MacIONVRAMState *s = opaque;
53: uint32_t ret;
54:
1.1.1.2 root 55: if (addr < s->size)
1.1 root 56: ret = s->data[addr];
57: else
58: ret = -1;
1.1.1.2 root 59: NVR_DPRINTF("read addr %04x val %x\n", addr, ret);
1.1 root 60:
61: return ret;
62: }
63:
64: void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
65: {
66: MacIONVRAMState *s = opaque;
67:
1.1.1.2 root 68: NVR_DPRINTF("write addr %04x val %x\n", addr, val);
69: if (addr < s->size)
1.1 root 70: s->data[addr] = val;
71: }
72:
73: /* macio style NVRAM device */
1.1.1.8 ! root 74: static void macio_nvram_writeb(void *opaque, target_phys_addr_t addr,
! 75: uint64_t value, unsigned size)
1.1 root 76: {
77: MacIONVRAMState *s = opaque;
78:
1.1.1.2 root 79: addr = (addr >> s->it_shift) & (s->size - 1);
1.1 root 80: s->data[addr] = value;
1.1.1.2 root 81: NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value);
1.1 root 82: }
83:
1.1.1.8 ! root 84: static uint64_t macio_nvram_readb(void *opaque, target_phys_addr_t addr,
! 85: unsigned size)
1.1 root 86: {
87: MacIONVRAMState *s = opaque;
88: uint32_t value;
89:
1.1.1.2 root 90: addr = (addr >> s->it_shift) & (s->size - 1);
1.1 root 91: value = s->data[addr];
1.1.1.2 root 92: NVR_DPRINTF("readb addr %04x val %x\n", (int)addr, value);
1.1 root 93:
94: return value;
95: }
96:
1.1.1.8 ! root 97: static const MemoryRegionOps macio_nvram_ops = {
! 98: .read = macio_nvram_readb,
! 99: .write = macio_nvram_writeb,
! 100: .endianness = DEVICE_NATIVE_ENDIAN,
1.1 root 101: };
102:
1.1.1.7 root 103: static const VMStateDescription vmstate_macio_nvram = {
104: .name = "macio_nvram",
105: .version_id = 1,
106: .minimum_version_id = 1,
107: .minimum_version_id_old = 1,
108: .fields = (VMStateField[]) {
109: VMSTATE_VBUFFER_UINT32(data, MacIONVRAMState, 0, NULL, 0, size),
110: VMSTATE_END_OF_LIST()
111: }
112: };
1.1.1.2 root 113:
114:
115: static void macio_nvram_reset(void *opaque)
116: {
117: }
118:
1.1.1.8 ! root 119: MacIONVRAMState *macio_nvram_init (target_phys_addr_t size,
1.1.1.2 root 120: unsigned int it_shift)
1.1 root 121: {
122: MacIONVRAMState *s;
123:
1.1.1.8 ! root 124: s = g_malloc0(sizeof(MacIONVRAMState));
! 125: s->data = g_malloc0(size);
1.1 root 126: s->size = size;
1.1.1.2 root 127: s->it_shift = it_shift;
128:
1.1.1.8 ! root 129: memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram",
! 130: size << it_shift);
1.1.1.7 root 131: vmstate_register(NULL, -1, &vmstate_macio_nvram, s);
1.1.1.2 root 132: qemu_register_reset(macio_nvram_reset, s);
1.1 root 133:
134: return s;
135: }
136:
1.1.1.8 ! root 137: void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
! 138: target_phys_addr_t mem_base)
1.1 root 139: {
1.1.1.8 ! root 140: memory_region_add_subregion(bar, mem_base, &s->mem);
1.1 root 141: }
142:
1.1.1.2 root 143: /* Set up a system OpenBIOS NVRAM partition */
1.1 root 144: void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len)
145: {
1.1.1.2 root 146: unsigned int i;
147: uint32_t start = 0, end;
148: struct OpenBIOS_nvpart_v1 *part_header;
149:
150: // OpenBIOS nvram variables
151: // Variable partition
152: part_header = (struct OpenBIOS_nvpart_v1 *)nvr->data;
153: part_header->signature = OPENBIOS_PART_SYSTEM;
154: pstrcpy(part_header->name, sizeof(part_header->name), "system");
155:
156: end = start + sizeof(struct OpenBIOS_nvpart_v1);
157: for (i = 0; i < nb_prom_envs; i++)
158: end = OpenBIOS_set_var(nvr->data, end, prom_envs[i]);
159:
160: // End marker
161: nvr->data[end++] = '\0';
162:
163: end = start + ((end - start + 15) & ~15);
164: /* XXX: OpenBIOS is not able to grow up a partition. Leave some space for
165: new variables. */
166: if (end < DEF_SYSTEM_SIZE)
167: end = DEF_SYSTEM_SIZE;
168: OpenBIOS_finish_partition(part_header, end - start);
169:
170: // free partition
171: start = end;
172: part_header = (struct OpenBIOS_nvpart_v1 *)&nvr->data[start];
173: part_header->signature = OPENBIOS_PART_FREE;
174: pstrcpy(part_header->name, sizeof(part_header->name), "free");
1.1 root 175:
1.1.1.2 root 176: end = len;
177: OpenBIOS_finish_partition(part_header, end - start);
1.1 root 178: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.