Statistics
| Branch: | Revision:

root / hw / nvram / mac_nvram.c @ a8aec295

History | View | Annotate | Download (5.7 kB)

1 3cbee15b j_mayer
/*
2 3cbee15b j_mayer
 * PowerMac NVRAM emulation
3 3cbee15b j_mayer
 *
4 3cbee15b j_mayer
 * Copyright (c) 2005-2007 Fabrice Bellard
5 3cbee15b j_mayer
 * Copyright (c) 2007 Jocelyn Mayer
6 3cbee15b j_mayer
 *
7 3cbee15b j_mayer
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 3cbee15b j_mayer
 * of this software and associated documentation files (the "Software"), to deal
9 3cbee15b j_mayer
 * in the Software without restriction, including without limitation the rights
10 3cbee15b j_mayer
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 3cbee15b j_mayer
 * copies of the Software, and to permit persons to whom the Software is
12 3cbee15b j_mayer
 * furnished to do so, subject to the following conditions:
13 3cbee15b j_mayer
 *
14 3cbee15b j_mayer
 * The above copyright notice and this permission notice shall be included in
15 3cbee15b j_mayer
 * all copies or substantial portions of the Software.
16 3cbee15b j_mayer
 *
17 3cbee15b j_mayer
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 3cbee15b j_mayer
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 3cbee15b j_mayer
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 3cbee15b j_mayer
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 3cbee15b j_mayer
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 3cbee15b j_mayer
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 3cbee15b j_mayer
 * THE SOFTWARE.
24 3cbee15b j_mayer
 */
25 83c9f4ca Paolo Bonzini
#include "hw/hw.h"
26 ec0503b4 Michael S. Tsirkin
#include "hw/nvram/openbios_firmware_abi.h"
27 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
28 83c9f4ca Paolo Bonzini
#include "hw/ppc/mac.h"
29 3cbee15b j_mayer
30 ea026b2f blueswir1
/* debug NVR */
31 ea026b2f blueswir1
//#define DEBUG_NVR
32 ea026b2f blueswir1
33 ea026b2f blueswir1
#ifdef DEBUG_NVR
34 001faf32 Blue Swirl
#define NVR_DPRINTF(fmt, ...)                                   \
35 001faf32 Blue Swirl
    do { printf("NVR: " fmt , ## __VA_ARGS__); } while (0)
36 ea026b2f blueswir1
#else
37 001faf32 Blue Swirl
#define NVR_DPRINTF(fmt, ...)
38 ea026b2f blueswir1
#endif
39 ea026b2f blueswir1
40 bd89f43f aurel32
#define DEF_SYSTEM_SIZE 0xc10
41 bd89f43f aurel32
42 3cbee15b j_mayer
/* Direct access to NVRAM */
43 3743cca7 Andreas Färber
uint8_t macio_nvram_read(MacIONVRAMState *s, uint32_t addr)
44 3cbee15b j_mayer
{
45 3cbee15b j_mayer
    uint32_t ret;
46 3cbee15b j_mayer
47 3743cca7 Andreas Färber
    if (addr < s->size) {
48 3cbee15b j_mayer
        ret = s->data[addr];
49 3743cca7 Andreas Färber
    } else {
50 3cbee15b j_mayer
        ret = -1;
51 3743cca7 Andreas Färber
    }
52 3743cca7 Andreas Färber
    NVR_DPRINTF("read addr %04" PRIx32 " val %" PRIx8 "\n", addr, ret);
53 3cbee15b j_mayer
54 3cbee15b j_mayer
    return ret;
55 3cbee15b j_mayer
}
56 3cbee15b j_mayer
57 3743cca7 Andreas Färber
void macio_nvram_write(MacIONVRAMState *s, uint32_t addr, uint8_t val)
58 3cbee15b j_mayer
{
59 3743cca7 Andreas Färber
    NVR_DPRINTF("write addr %04" PRIx32 " val %" PRIx8 "\n", addr, val);
60 3743cca7 Andreas Färber
    if (addr < s->size) {
61 3cbee15b j_mayer
        s->data[addr] = val;
62 3743cca7 Andreas Färber
    }
63 3cbee15b j_mayer
}
64 3cbee15b j_mayer
65 3cbee15b j_mayer
/* macio style NVRAM device */
66 a8170e5e Avi Kivity
static void macio_nvram_writeb(void *opaque, hwaddr addr,
67 23c5e4ca Avi Kivity
                               uint64_t value, unsigned size)
68 3cbee15b j_mayer
{
69 3cbee15b j_mayer
    MacIONVRAMState *s = opaque;
70 74e91155 j_mayer
71 68af3f24 blueswir1
    addr = (addr >> s->it_shift) & (s->size - 1);
72 3cbee15b j_mayer
    s->data[addr] = value;
73 3743cca7 Andreas Färber
    NVR_DPRINTF("writeb addr %04" PHYS_PRIx " val %" PRIx64 "\n", addr, value);
74 3cbee15b j_mayer
}
75 3cbee15b j_mayer
76 a8170e5e Avi Kivity
static uint64_t macio_nvram_readb(void *opaque, hwaddr addr,
77 23c5e4ca Avi Kivity
                                  unsigned size)
78 3cbee15b j_mayer
{
79 3cbee15b j_mayer
    MacIONVRAMState *s = opaque;
80 3cbee15b j_mayer
    uint32_t value;
81 3cbee15b j_mayer
82 68af3f24 blueswir1
    addr = (addr >> s->it_shift) & (s->size - 1);
83 3cbee15b j_mayer
    value = s->data[addr];
84 ea026b2f blueswir1
    NVR_DPRINTF("readb addr %04x val %x\n", (int)addr, value);
85 3cbee15b j_mayer
86 3cbee15b j_mayer
    return value;
87 3cbee15b j_mayer
}
88 3cbee15b j_mayer
89 23c5e4ca Avi Kivity
static const MemoryRegionOps macio_nvram_ops = {
90 23c5e4ca Avi Kivity
    .read = macio_nvram_readb,
91 23c5e4ca Avi Kivity
    .write = macio_nvram_writeb,
92 d8c6d07f Andreas Färber
    .endianness = DEVICE_BIG_ENDIAN,
93 3cbee15b j_mayer
};
94 3cbee15b j_mayer
95 8e470f8a Juan Quintela
static const VMStateDescription vmstate_macio_nvram = {
96 8e470f8a Juan Quintela
    .name = "macio_nvram",
97 8e470f8a Juan Quintela
    .version_id = 1,
98 8e470f8a Juan Quintela
    .minimum_version_id = 1,
99 8e470f8a Juan Quintela
    .minimum_version_id_old = 1,
100 8e470f8a Juan Quintela
    .fields      = (VMStateField[]) {
101 8e470f8a Juan Quintela
        VMSTATE_VBUFFER_UINT32(data, MacIONVRAMState, 0, NULL, 0, size),
102 8e470f8a Juan Quintela
        VMSTATE_END_OF_LIST()
103 8e470f8a Juan Quintela
    }
104 8e470f8a Juan Quintela
};
105 9b64997f blueswir1
106 9b64997f blueswir1
107 95ed3b7c Andreas Färber
static void macio_nvram_reset(DeviceState *dev)
108 6e6b7363 blueswir1
{
109 6e6b7363 blueswir1
}
110 6e6b7363 blueswir1
111 95ed3b7c Andreas Färber
static void macio_nvram_realizefn(DeviceState *dev, Error **errp)
112 3cbee15b j_mayer
{
113 95ed3b7c Andreas Färber
    SysBusDevice *d = SYS_BUS_DEVICE(dev);
114 95ed3b7c Andreas Färber
    MacIONVRAMState *s = MACIO_NVRAM(dev);
115 74e91155 j_mayer
116 95ed3b7c Andreas Färber
    s->data = g_malloc0(s->size);
117 3f7cbbbd aurel32
118 23c5e4ca Avi Kivity
    memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram",
119 95ed3b7c Andreas Färber
                          s->size << s->it_shift);
120 95ed3b7c Andreas Färber
    sysbus_init_mmio(d, &s->mem);
121 95ed3b7c Andreas Färber
}
122 95ed3b7c Andreas Färber
123 95ed3b7c Andreas Färber
static void macio_nvram_unrealizefn(DeviceState *dev, Error **errp)
124 95ed3b7c Andreas Färber
{
125 95ed3b7c Andreas Färber
    MacIONVRAMState *s = MACIO_NVRAM(dev);
126 95ed3b7c Andreas Färber
127 95ed3b7c Andreas Färber
    g_free(s->data);
128 95ed3b7c Andreas Färber
}
129 3cbee15b j_mayer
130 95ed3b7c Andreas Färber
static Property macio_nvram_properties[] = {
131 95ed3b7c Andreas Färber
    DEFINE_PROP_UINT32("size", MacIONVRAMState, size, 0),
132 95ed3b7c Andreas Färber
    DEFINE_PROP_UINT32("it_shift", MacIONVRAMState, it_shift, 0),
133 95ed3b7c Andreas Färber
    DEFINE_PROP_END_OF_LIST()
134 95ed3b7c Andreas Färber
};
135 95ed3b7c Andreas Färber
136 95ed3b7c Andreas Färber
static void macio_nvram_class_init(ObjectClass *oc, void *data)
137 95ed3b7c Andreas Färber
{
138 95ed3b7c Andreas Färber
    DeviceClass *dc = DEVICE_CLASS(oc);
139 95ed3b7c Andreas Färber
140 95ed3b7c Andreas Färber
    dc->realize = macio_nvram_realizefn;
141 95ed3b7c Andreas Färber
    dc->unrealize = macio_nvram_unrealizefn;
142 95ed3b7c Andreas Färber
    dc->reset = macio_nvram_reset;
143 95ed3b7c Andreas Färber
    dc->vmsd = &vmstate_macio_nvram;
144 95ed3b7c Andreas Färber
    dc->props = macio_nvram_properties;
145 3cbee15b j_mayer
}
146 3cbee15b j_mayer
147 95ed3b7c Andreas Färber
static const TypeInfo macio_nvram_type_info = {
148 95ed3b7c Andreas Färber
    .name = TYPE_MACIO_NVRAM,
149 95ed3b7c Andreas Färber
    .parent = TYPE_SYS_BUS_DEVICE,
150 95ed3b7c Andreas Färber
    .instance_size = sizeof(MacIONVRAMState),
151 95ed3b7c Andreas Färber
    .class_init = macio_nvram_class_init,
152 95ed3b7c Andreas Färber
};
153 95ed3b7c Andreas Färber
154 95ed3b7c Andreas Färber
static void macio_nvram_register_types(void)
155 74e91155 j_mayer
{
156 95ed3b7c Andreas Färber
    type_register_static(&macio_nvram_type_info);
157 74e91155 j_mayer
}
158 74e91155 j_mayer
159 95efd11c blueswir1
/* Set up a system OpenBIOS NVRAM partition */
160 3cbee15b j_mayer
void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len)
161 3cbee15b j_mayer
{
162 95efd11c blueswir1
    unsigned int i;
163 95efd11c blueswir1
    uint32_t start = 0, end;
164 95efd11c blueswir1
    struct OpenBIOS_nvpart_v1 *part_header;
165 95efd11c blueswir1
166 95efd11c blueswir1
    // OpenBIOS nvram variables
167 95efd11c blueswir1
    // Variable partition
168 95efd11c blueswir1
    part_header = (struct OpenBIOS_nvpart_v1 *)nvr->data;
169 95efd11c blueswir1
    part_header->signature = OPENBIOS_PART_SYSTEM;
170 95efd11c blueswir1
    pstrcpy(part_header->name, sizeof(part_header->name), "system");
171 95efd11c blueswir1
172 95efd11c blueswir1
    end = start + sizeof(struct OpenBIOS_nvpart_v1);
173 95efd11c blueswir1
    for (i = 0; i < nb_prom_envs; i++)
174 95efd11c blueswir1
        end = OpenBIOS_set_var(nvr->data, end, prom_envs[i]);
175 95efd11c blueswir1
176 95efd11c blueswir1
    // End marker
177 95efd11c blueswir1
    nvr->data[end++] = '\0';
178 95efd11c blueswir1
179 95efd11c blueswir1
    end = start + ((end - start + 15) & ~15);
180 bd89f43f aurel32
    /* XXX: OpenBIOS is not able to grow up a partition. Leave some space for
181 bd89f43f aurel32
       new variables. */
182 bd89f43f aurel32
    if (end < DEF_SYSTEM_SIZE)
183 bd89f43f aurel32
        end = DEF_SYSTEM_SIZE;
184 95efd11c blueswir1
    OpenBIOS_finish_partition(part_header, end - start);
185 95efd11c blueswir1
186 95efd11c blueswir1
    // free partition
187 95efd11c blueswir1
    start = end;
188 95efd11c blueswir1
    part_header = (struct OpenBIOS_nvpart_v1 *)&nvr->data[start];
189 95efd11c blueswir1
    part_header->signature = OPENBIOS_PART_FREE;
190 95efd11c blueswir1
    pstrcpy(part_header->name, sizeof(part_header->name), "free");
191 95efd11c blueswir1
192 95efd11c blueswir1
    end = len;
193 95efd11c blueswir1
    OpenBIOS_finish_partition(part_header, end - start);
194 3cbee15b j_mayer
}
195 95ed3b7c Andreas Färber
196 95ed3b7c Andreas Färber
type_init(macio_nvram_register_types)