|
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" |
|
26 #include "ppc_mac.h" |
|
27 |
|
28 struct MacIONVRAMState { |
|
29 target_phys_addr_t size; |
|
30 int mem_index; |
|
31 uint8_t data[0x2000]; |
|
32 }; |
|
33 |
|
34 /* Direct access to NVRAM */ |
|
35 uint32_t macio_nvram_read (void *opaque, uint32_t addr) |
|
36 { |
|
37 MacIONVRAMState *s = opaque; |
|
38 uint32_t ret; |
|
39 |
|
40 // printf("%s: %p addr %04x\n", __func__, s, addr); |
|
41 if (addr < 0x2000) |
|
42 ret = s->data[addr]; |
|
43 else |
|
44 ret = -1; |
|
45 |
|
46 return ret; |
|
47 } |
|
48 |
|
49 void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val) |
|
50 { |
|
51 MacIONVRAMState *s = opaque; |
|
52 |
|
53 // printf("%s: %p addr %04x val %02x\n", __func__, s, addr, val); |
|
54 if (addr < 0x2000) |
|
55 s->data[addr] = val; |
|
56 } |
|
57 |
|
58 /* macio style NVRAM device */ |
|
59 static void macio_nvram_writeb (void *opaque, |
|
60 target_phys_addr_t addr, uint32_t value) |
|
61 { |
|
62 MacIONVRAMState *s = opaque; |
|
63 |
|
64 addr = (addr >> 4) & 0x1fff; |
|
65 s->data[addr] = value; |
|
66 // printf("macio_nvram_writeb %04x = %02x\n", addr, value); |
|
67 } |
|
68 |
|
69 static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr) |
|
70 { |
|
71 MacIONVRAMState *s = opaque; |
|
72 uint32_t value; |
|
73 |
|
74 addr = (addr >> 4) & 0x1fff; |
|
75 value = s->data[addr]; |
|
76 // printf("macio_nvram_readb %04x = %02x\n", addr, value); |
|
77 |
|
78 return value; |
|
79 } |
|
80 |
|
81 static CPUWriteMemoryFunc *nvram_write[] = { |
|
82 &macio_nvram_writeb, |
|
83 &macio_nvram_writeb, |
|
84 &macio_nvram_writeb, |
|
85 }; |
|
86 |
|
87 static CPUReadMemoryFunc *nvram_read[] = { |
|
88 &macio_nvram_readb, |
|
89 &macio_nvram_readb, |
|
90 &macio_nvram_readb, |
|
91 }; |
|
92 |
|
93 MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size) |
|
94 { |
|
95 MacIONVRAMState *s; |
|
96 |
|
97 s = qemu_mallocz(sizeof(MacIONVRAMState)); |
|
98 if (!s) |
|
99 return NULL; |
|
100 s->size = size; |
|
101 s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s); |
|
102 *mem_index = s->mem_index; |
|
103 |
|
104 return s; |
|
105 } |
|
106 |
|
107 void macio_nvram_map (void *opaque, target_phys_addr_t mem_base) |
|
108 { |
|
109 MacIONVRAMState *s; |
|
110 |
|
111 s = opaque; |
|
112 cpu_register_physical_memory(mem_base, s->size, s->mem_index); |
|
113 } |
|
114 |
|
115 static uint8_t nvram_chksum (const uint8_t *buf, int n) |
|
116 { |
|
117 int sum, i; |
|
118 sum = 0; |
|
119 for(i = 0; i < n; i++) |
|
120 sum += buf[i]; |
|
121 return (sum & 0xff) + (sum >> 8); |
|
122 } |
|
123 |
|
124 /* set a free Mac OS NVRAM partition */ |
|
125 void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len) |
|
126 { |
|
127 uint8_t *buf; |
|
128 char partition_name[12] = "wwwwwwwwwwww"; |
|
129 |
|
130 buf = nvr->data; |
|
131 buf[0] = 0x7f; /* free partition magic */ |
|
132 buf[1] = 0; /* checksum */ |
|
133 buf[2] = len >> 8; |
|
134 buf[3] = len; |
|
135 memcpy(buf + 4, partition_name, 12); |
|
136 buf[1] = nvram_chksum(buf, 16); |
|
137 } |