Commit d2c63fc185f3d126ef177105166a491ab3556f5c
1 parent
57c26279
Update OHW interface to version 3.
Use common ABI description file with OpenBIOS. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3648 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
324 additions
and
254 deletions
hw/firmware_abi.h
0 → 100755
| 1 | +#ifndef FIRMWARE_ABI_H | |
| 2 | +#define FIRMWARE_ABI_H | |
| 3 | + | |
| 4 | +#ifndef __ASSEMBLY__ | |
| 5 | +/* Open Hack'Ware NVRAM configuration structure */ | |
| 6 | + | |
| 7 | +/* Version 3 */ | |
| 8 | +typedef struct ohwcfg_v3_t ohwcfg_v3_t; | |
| 9 | +struct ohwcfg_v3_t { | |
| 10 | + /* 0x00: structure identifier */ | |
| 11 | + uint8_t struct_ident[0x10]; | |
| 12 | + /* 0x10: structure version and NVRAM description */ | |
| 13 | + uint32_t struct_version; | |
| 14 | + uint16_t nvram_size; | |
| 15 | + uint16_t pad0; | |
| 16 | + uint16_t nvram_arch_ptr; | |
| 17 | + uint16_t nvram_arch_size; | |
| 18 | + uint16_t nvram_arch_crc; | |
| 19 | + uint8_t pad1[0x02]; | |
| 20 | + /* 0x20: host architecture */ | |
| 21 | + uint8_t arch[0x10]; | |
| 22 | + /* 0x30: RAM/ROM description */ | |
| 23 | + uint64_t RAM0_base; | |
| 24 | + uint64_t RAM0_size; | |
| 25 | + uint64_t RAM1_base; | |
| 26 | + uint64_t RAM1_size; | |
| 27 | + uint64_t RAM2_base; | |
| 28 | + uint64_t RAM2_size; | |
| 29 | + uint64_t RAM3_base; | |
| 30 | + uint64_t RAM3_size; | |
| 31 | + uint64_t ROM_base; | |
| 32 | + uint64_t ROM_size; | |
| 33 | + /* 0x80: Kernel description */ | |
| 34 | + uint64_t kernel_image; | |
| 35 | + uint64_t kernel_size; | |
| 36 | + /* 0x90: Kernel command line */ | |
| 37 | + uint64_t cmdline; | |
| 38 | + uint64_t cmdline_size; | |
| 39 | + /* 0xA0: Kernel boot image */ | |
| 40 | + uint64_t initrd_image; | |
| 41 | + uint64_t initrd_size; | |
| 42 | + /* 0xB0: NVRAM image */ | |
| 43 | + uint64_t NVRAM_image; | |
| 44 | + uint8_t pad2[8]; | |
| 45 | + /* 0xC0: graphic configuration */ | |
| 46 | + uint16_t width; | |
| 47 | + uint16_t height; | |
| 48 | + uint16_t depth; | |
| 49 | + uint16_t graphic_flags; | |
| 50 | + /* 0xC8: CPUs description */ | |
| 51 | + uint8_t nb_cpus; | |
| 52 | + uint8_t boot_cpu; | |
| 53 | + uint8_t nboot_devices; | |
| 54 | + uint8_t pad3[5]; | |
| 55 | + /* 0xD0: boot devices */ | |
| 56 | + uint8_t boot_devices[0x10]; | |
| 57 | + /* 0xE0 */ | |
| 58 | + uint8_t pad4[0x1C]; /* 28 */ | |
| 59 | + /* 0xFC: checksum */ | |
| 60 | + uint16_t crc; | |
| 61 | + uint8_t pad5[0x02]; | |
| 62 | +} __attribute__ (( packed )); | |
| 63 | + | |
| 64 | +#define OHW_GF_NOGRAPHICS 0x0001 | |
| 65 | + | |
| 66 | +static inline uint16_t | |
| 67 | +OHW_crc_update (uint16_t prev, uint16_t value) | |
| 68 | +{ | |
| 69 | + uint16_t tmp; | |
| 70 | + uint16_t pd, pd1, pd2; | |
| 71 | + | |
| 72 | + tmp = prev >> 8; | |
| 73 | + pd = prev ^ value; | |
| 74 | + pd1 = pd & 0x000F; | |
| 75 | + pd2 = ((pd >> 4) & 0x000F) ^ pd1; | |
| 76 | + tmp ^= (pd1 << 3) | (pd1 << 8); | |
| 77 | + tmp ^= pd2 | (pd2 << 7) | (pd2 << 12); | |
| 78 | + | |
| 79 | + return tmp; | |
| 80 | +} | |
| 81 | + | |
| 82 | +static inline uint16_t | |
| 83 | +OHW_compute_crc (ohwcfg_v3_t *header, uint32_t start, uint32_t count) | |
| 84 | +{ | |
| 85 | + uint32_t i; | |
| 86 | + uint16_t crc = 0xFFFF; | |
| 87 | + uint8_t *ptr = (uint8_t *)header; | |
| 88 | + int odd; | |
| 89 | + | |
| 90 | + odd = count & 1; | |
| 91 | + count &= ~1; | |
| 92 | + for (i = 0; i != count; i++) { | |
| 93 | + crc = OHW_crc_update(crc, (ptr[start + i] << 8) | ptr[start + i + 1]); | |
| 94 | + } | |
| 95 | + if (odd) { | |
| 96 | + crc = OHW_crc_update(crc, ptr[start + i] << 8); | |
| 97 | + } | |
| 98 | + | |
| 99 | + return crc; | |
| 100 | +} | |
| 101 | + | |
| 102 | +/* Sparc32 runtime NVRAM structure for SMP CPU boot */ | |
| 103 | +struct sparc_arch_cfg { | |
| 104 | + uint32_t smp_ctx; | |
| 105 | + uint32_t smp_ctxtbl; | |
| 106 | + uint32_t smp_entry; | |
| 107 | + uint8_t valid; | |
| 108 | + uint8_t unused[51]; | |
| 109 | +}; | |
| 110 | + | |
| 111 | +/* OpenBIOS NVRAM partition */ | |
| 112 | +struct OpenBIOS_nvpart_v1 { | |
| 113 | + uint8_t signature; | |
| 114 | + uint8_t checksum; | |
| 115 | + uint16_t len; // BE, length divided by 16 | |
| 116 | + char name[12]; | |
| 117 | +}; | |
| 118 | + | |
| 119 | +#define OPENBIOS_PART_SYSTEM 0x70 | |
| 120 | +#define OPENBIOS_PART_FREE 0x7f | |
| 121 | + | |
| 122 | +static inline void | |
| 123 | +OpenBIOS_finish_partition(struct OpenBIOS_nvpart_v1 *header, uint32_t size) | |
| 124 | +{ | |
| 125 | + unsigned int i, sum; | |
| 126 | + uint8_t *tmpptr; | |
| 127 | + | |
| 128 | + // Length divided by 16 | |
| 129 | + header->len = cpu_to_be16(size >> 4); | |
| 130 | + | |
| 131 | + // Checksum | |
| 132 | + tmpptr = (uint8_t *)header; | |
| 133 | + sum = *tmpptr; | |
| 134 | + for (i = 0; i < 14; i++) { | |
| 135 | + sum += tmpptr[2 + i]; | |
| 136 | + sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; | |
| 137 | + } | |
| 138 | + header->checksum = sum & 0xff; | |
| 139 | +} | |
| 140 | + | |
| 141 | +static inline uint32_t | |
| 142 | +OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const unsigned char *str) | |
| 143 | +{ | |
| 144 | + uint32_t len; | |
| 145 | + | |
| 146 | + len = strlen(str) + 1; | |
| 147 | + memcpy(&nvram[addr], str, len); | |
| 148 | + | |
| 149 | + return addr + len; | |
| 150 | +} | |
| 151 | + | |
| 152 | +/* Sun IDPROM structure at the end of NVRAM */ | |
| 153 | +struct Sun_nvram { | |
| 154 | + uint8_t type; | |
| 155 | + uint8_t machine_id; | |
| 156 | + uint8_t macaddr[6]; | |
| 157 | + uint8_t unused[7]; | |
| 158 | + uint8_t checksum; | |
| 159 | +}; | |
| 160 | + | |
| 161 | +static inline void | |
| 162 | +Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id) | |
| 163 | +{ | |
| 164 | + uint8_t tmp, *tmpptr; | |
| 165 | + unsigned int i; | |
| 166 | + | |
| 167 | + header->type = 1; | |
| 168 | + header->machine_id = machine_id & 0xff; | |
| 169 | + memcpy(&header->macaddr, macaddr, 6); | |
| 170 | + /* Calculate checksum */ | |
| 171 | + tmp = 0; | |
| 172 | + tmpptr = (uint8_t *)header; | |
| 173 | + for (i = 0; i < 15; i++) | |
| 174 | + tmp ^= tmpptr[i]; | |
| 175 | + | |
| 176 | + header->checksum = tmp; | |
| 177 | +} | |
| 178 | + | |
| 179 | +#else /* __ASSEMBLY__ */ | |
| 180 | + | |
| 181 | +/* Structure offsets for asm use */ | |
| 182 | + | |
| 183 | +/* Open Hack'Ware NVRAM configuration structure */ | |
| 184 | +#define OHW_ARCH_PTR 0x18 | |
| 185 | +#define OHW_RAM_SIZE 0x38 | |
| 186 | +#define OHW_BOOT_CPU 0xC9 | |
| 187 | + | |
| 188 | +/* Sparc32 runtime NVRAM structure for SMP CPU boot */ | |
| 189 | +#define SPARC_SMP_CTX 0x0 | |
| 190 | +#define SPARC_SMP_CTXTBL 0x4 | |
| 191 | +#define SPARC_SMP_ENTRY 0x8 | |
| 192 | +#define SPARC_SMP_VALID 0xc | |
| 193 | + | |
| 194 | +/* Sun IDPROM structure at the end of NVRAM */ | |
| 195 | +#define SPARC_MACHINE_ID 0x1fd9 | |
| 196 | + | |
| 197 | +#endif /* __ASSEMBLY__ */ | |
| 198 | +#endif /* FIRMWARE_ABI_H */ | ... | ... |
hw/sun4m.c
| ... | ... | @@ -22,6 +22,9 @@ |
| 22 | 22 | * THE SOFTWARE. |
| 23 | 23 | */ |
| 24 | 24 | #include "vl.h" |
| 25 | +#include "m48t59.h" | |
| 26 | +#include "firmware_abi.h" | |
| 27 | + | |
| 25 | 28 | //#define DEBUG_IRQ |
| 26 | 29 | |
| 27 | 30 | /* |
| ... | ... | @@ -102,131 +105,87 @@ void DMA_register_channel (int nchan, |
| 102 | 105 | { |
| 103 | 106 | } |
| 104 | 107 | |
| 105 | -static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value) | |
| 106 | -{ | |
| 107 | - m48t59_write(nvram, addr++, (value >> 8) & 0xff); | |
| 108 | - m48t59_write(nvram, addr++, value & 0xff); | |
| 109 | -} | |
| 110 | - | |
| 111 | -static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value) | |
| 112 | -{ | |
| 113 | - m48t59_write(nvram, addr++, value >> 24); | |
| 114 | - m48t59_write(nvram, addr++, (value >> 16) & 0xff); | |
| 115 | - m48t59_write(nvram, addr++, (value >> 8) & 0xff); | |
| 116 | - m48t59_write(nvram, addr++, value & 0xff); | |
| 117 | -} | |
| 118 | - | |
| 119 | -static void nvram_set_string (m48t59_t *nvram, uint32_t addr, | |
| 120 | - const unsigned char *str, uint32_t max) | |
| 121 | -{ | |
| 122 | - unsigned int i; | |
| 123 | - | |
| 124 | - for (i = 0; i < max && str[i] != '\0'; i++) { | |
| 125 | - m48t59_write(nvram, addr + i, str[i]); | |
| 126 | - } | |
| 127 | - m48t59_write(nvram, addr + max - 1, '\0'); | |
| 128 | -} | |
| 129 | - | |
| 130 | -static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr, | |
| 131 | - const unsigned char *str) | |
| 132 | -{ | |
| 133 | - uint32_t len; | |
| 134 | - | |
| 135 | - len = strlen(str) + 1; | |
| 136 | - nvram_set_string(nvram, addr, str, len); | |
| 137 | - | |
| 138 | - return addr + len; | |
| 139 | -} | |
| 140 | - | |
| 141 | -static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, | |
| 142 | - uint32_t end) | |
| 143 | -{ | |
| 144 | - unsigned int i, sum; | |
| 145 | - | |
| 146 | - // Length divided by 16 | |
| 147 | - m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff); | |
| 148 | - m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff); | |
| 149 | - // Checksum | |
| 150 | - sum = m48t59_read(nvram, start); | |
| 151 | - for (i = 0; i < 14; i++) { | |
| 152 | - sum += m48t59_read(nvram, start + 2 + i); | |
| 153 | - sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; | |
| 154 | - } | |
| 155 | - m48t59_write(nvram, start + 1, sum & 0xff); | |
| 156 | -} | |
| 157 | - | |
| 158 | 108 | extern int nographic; |
| 159 | 109 | |
| 160 | 110 | static void nvram_init(m48t59_t *nvram, uint8_t *macaddr, const char *cmdline, |
| 161 | - const char *boot_device, uint32_t RAM_size, | |
| 111 | + const char *boot_devices, uint32_t RAM_size, | |
| 162 | 112 | uint32_t kernel_size, |
| 163 | 113 | int width, int height, int depth, |
| 164 | 114 | int machine_id) |
| 165 | 115 | { |
| 166 | - unsigned char tmp = 0; | |
| 167 | - unsigned int i, j; | |
| 116 | + unsigned int i; | |
| 168 | 117 | uint32_t start, end; |
| 118 | + uint8_t image[0x1ff0]; | |
| 119 | + ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ | |
| 120 | + struct sparc_arch_cfg *sparc_header; | |
| 121 | + struct OpenBIOS_nvpart_v1 *part_header; | |
| 122 | + | |
| 123 | + memset(image, '\0', sizeof(image)); | |
| 169 | 124 | |
| 170 | 125 | // Try to match PPC NVRAM |
| 171 | - nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16); | |
| 172 | - nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */ | |
| 173 | - // NVRAM_size, arch not applicable | |
| 174 | - m48t59_write(nvram, 0x2D, smp_cpus & 0xff); | |
| 175 | - m48t59_write(nvram, 0x2E, 0); | |
| 176 | - m48t59_write(nvram, 0x2F, nographic & 0xff); | |
| 177 | - nvram_set_lword(nvram, 0x30, RAM_size); | |
| 178 | - m48t59_write(nvram, 0x34, boot_device[0] & 0xff); | |
| 179 | - nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR); | |
| 180 | - nvram_set_lword(nvram, 0x3C, kernel_size); | |
| 126 | + strcpy(header->struct_ident, "QEMU_BIOS"); | |
| 127 | + header->struct_version = cpu_to_be32(3); /* structure v3 */ | |
| 128 | + | |
| 129 | + header->nvram_size = cpu_to_be16(0x2000); | |
| 130 | + header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); | |
| 131 | + header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); | |
| 132 | + strcpy(header->arch, "sun4m"); | |
| 133 | + header->nb_cpus = smp_cpus & 0xff; | |
| 134 | + header->RAM0_base = 0; | |
| 135 | + header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); | |
| 136 | + strcpy(header->boot_devices, boot_devices); | |
| 137 | + header->nboot_devices = strlen(boot_devices) & 0xff; | |
| 138 | + header->kernel_image = cpu_to_be64((uint64_t)KERNEL_LOAD_ADDR); | |
| 139 | + header->kernel_size = cpu_to_be64((uint64_t)kernel_size); | |
| 181 | 140 | if (cmdline) { |
| 182 | 141 | strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); |
| 183 | - nvram_set_lword(nvram, 0x40, CMDLINE_ADDR); | |
| 184 | - nvram_set_lword(nvram, 0x44, strlen(cmdline)); | |
| 142 | + header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); | |
| 143 | + header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); | |
| 185 | 144 | } |
| 186 | - // initrd_image, initrd_size passed differently | |
| 187 | - nvram_set_word(nvram, 0x54, width); | |
| 188 | - nvram_set_word(nvram, 0x56, height); | |
| 189 | - nvram_set_word(nvram, 0x58, depth); | |
| 145 | + // XXX add initrd_image, initrd_size | |
| 146 | + header->width = cpu_to_be16(width); | |
| 147 | + header->height = cpu_to_be16(height); | |
| 148 | + header->depth = cpu_to_be16(depth); | |
| 149 | + if (nographic) | |
| 150 | + header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS); | |
| 151 | + | |
| 152 | + header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); | |
| 153 | + | |
| 154 | + // Architecture specific header | |
| 155 | + start = sizeof(ohwcfg_v3_t); | |
| 156 | + sparc_header = (struct sparc_arch_cfg *)&image[start]; | |
| 157 | + sparc_header->valid = 0; | |
| 158 | + start += sizeof(struct sparc_arch_cfg); | |
| 190 | 159 | |
| 191 | 160 | // OpenBIOS nvram variables |
| 192 | 161 | // Variable partition |
| 193 | - start = 252; | |
| 194 | - m48t59_write(nvram, start, 0x70); | |
| 195 | - nvram_set_string(nvram, start + 4, "system", 12); | |
| 162 | + part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | |
| 163 | + part_header->signature = OPENBIOS_PART_SYSTEM; | |
| 164 | + strcpy(part_header->name, "system"); | |
| 196 | 165 | |
| 197 | - end = start + 16; | |
| 166 | + end = start + sizeof(struct OpenBIOS_nvpart_v1); | |
| 198 | 167 | for (i = 0; i < nb_prom_envs; i++) |
| 199 | - end = nvram_set_var(nvram, end, prom_envs[i]); | |
| 168 | + end = OpenBIOS_set_var(image, end, prom_envs[i]); | |
| 169 | + | |
| 170 | + // End marker | |
| 171 | + image[end++] = '\0'; | |
| 200 | 172 | |
| 201 | - m48t59_write(nvram, end++ , 0); | |
| 202 | 173 | end = start + ((end - start + 15) & ~15); |
| 203 | - nvram_finish_partition(nvram, start, end); | |
| 174 | + OpenBIOS_finish_partition(part_header, end - start); | |
| 204 | 175 | |
| 205 | 176 | // free partition |
| 206 | 177 | start = end; |
| 207 | - m48t59_write(nvram, start, 0x7f); | |
| 208 | - nvram_set_string(nvram, start + 4, "free", 12); | |
| 178 | + part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | |
| 179 | + part_header->signature = OPENBIOS_PART_FREE; | |
| 180 | + strcpy(part_header->name, "free"); | |
| 209 | 181 | |
| 210 | 182 | end = 0x1fd0; |
| 211 | - nvram_finish_partition(nvram, start, end); | |
| 212 | - | |
| 213 | - // Sun4m specific use | |
| 214 | - start = i = 0x1fd8; | |
| 215 | - m48t59_write(nvram, i++, 0x01); | |
| 216 | - m48t59_write(nvram, i++, machine_id); | |
| 217 | - j = 0; | |
| 218 | - m48t59_write(nvram, i++, macaddr[j++]); | |
| 219 | - m48t59_write(nvram, i++, macaddr[j++]); | |
| 220 | - m48t59_write(nvram, i++, macaddr[j++]); | |
| 221 | - m48t59_write(nvram, i++, macaddr[j++]); | |
| 222 | - m48t59_write(nvram, i++, macaddr[j++]); | |
| 223 | - m48t59_write(nvram, i, macaddr[j]); | |
| 224 | - | |
| 225 | - /* Calculate checksum */ | |
| 226 | - for (i = start; i < start + 15; i++) { | |
| 227 | - tmp ^= m48t59_read(nvram, i); | |
| 228 | - } | |
| 229 | - m48t59_write(nvram, start + 15, tmp); | |
| 183 | + OpenBIOS_finish_partition(part_header, end - start); | |
| 184 | + | |
| 185 | + Sun_init_header((struct Sun_nvram *)&image[0x1fd8], macaddr, machine_id); | |
| 186 | + | |
| 187 | + for (i = 0; i < sizeof(image); i++) | |
| 188 | + m48t59_write(nvram, i, image[i]); | |
| 230 | 189 | } |
| 231 | 190 | |
| 232 | 191 | static void *slavio_intctl; | ... | ... |
hw/sun4u.c
| ... | ... | @@ -23,6 +23,7 @@ |
| 23 | 23 | */ |
| 24 | 24 | #include "vl.h" |
| 25 | 25 | #include "m48t59.h" |
| 26 | +#include "firmware_abi.h" | |
| 26 | 27 | |
| 27 | 28 | #define KERNEL_LOAD_ADDR 0x00404000 |
| 28 | 29 | #define CMDLINE_ADDR 0x003ff000 |
| ... | ... | @@ -66,179 +67,91 @@ void DMA_register_channel (int nchan, |
| 66 | 67 | { |
| 67 | 68 | } |
| 68 | 69 | |
| 69 | -/* NVRAM helpers */ | |
| 70 | -static void nvram_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value) | |
| 71 | -{ | |
| 72 | - m48t59_write(nvram, addr, value); | |
| 73 | -} | |
| 74 | - | |
| 75 | -static uint8_t nvram_get_byte (m48t59_t *nvram, uint32_t addr) | |
| 76 | -{ | |
| 77 | - return m48t59_read(nvram, addr); | |
| 78 | -} | |
| 79 | - | |
| 80 | -static void nvram_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value) | |
| 81 | -{ | |
| 82 | - m48t59_write(nvram, addr++, (value >> 8) & 0xff); | |
| 83 | - m48t59_write(nvram, addr++, value & 0xff); | |
| 84 | -} | |
| 85 | - | |
| 86 | -static uint16_t nvram_get_word (m48t59_t *nvram, uint32_t addr) | |
| 87 | -{ | |
| 88 | - uint16_t tmp; | |
| 89 | - | |
| 90 | - tmp = m48t59_read(nvram, addr) << 8; | |
| 91 | - tmp |= m48t59_read(nvram, addr + 1); | |
| 92 | - | |
| 93 | - return tmp; | |
| 94 | -} | |
| 95 | - | |
| 96 | -static void nvram_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value) | |
| 97 | -{ | |
| 98 | - m48t59_write(nvram, addr++, value >> 24); | |
| 99 | - m48t59_write(nvram, addr++, (value >> 16) & 0xff); | |
| 100 | - m48t59_write(nvram, addr++, (value >> 8) & 0xff); | |
| 101 | - m48t59_write(nvram, addr++, value & 0xff); | |
| 102 | -} | |
| 103 | - | |
| 104 | -static void nvram_set_string (m48t59_t *nvram, uint32_t addr, | |
| 105 | - const unsigned char *str, uint32_t max) | |
| 106 | -{ | |
| 107 | - unsigned int i; | |
| 108 | - | |
| 109 | - for (i = 0; i < max && str[i] != '\0'; i++) { | |
| 110 | - m48t59_write(nvram, addr + i, str[i]); | |
| 111 | - } | |
| 112 | - m48t59_write(nvram, addr + max - 1, '\0'); | |
| 113 | -} | |
| 114 | - | |
| 115 | -static uint16_t nvram_crc_update (uint16_t prev, uint16_t value) | |
| 116 | -{ | |
| 117 | - uint16_t tmp; | |
| 118 | - uint16_t pd, pd1, pd2; | |
| 119 | - | |
| 120 | - tmp = prev >> 8; | |
| 121 | - pd = prev ^ value; | |
| 122 | - pd1 = pd & 0x000F; | |
| 123 | - pd2 = ((pd >> 4) & 0x000F) ^ pd1; | |
| 124 | - tmp ^= (pd1 << 3) | (pd1 << 8); | |
| 125 | - tmp ^= pd2 | (pd2 << 7) | (pd2 << 12); | |
| 126 | - | |
| 127 | - return tmp; | |
| 128 | -} | |
| 129 | - | |
| 130 | -static uint16_t nvram_compute_crc (m48t59_t *nvram, uint32_t start, | |
| 131 | - uint32_t count) | |
| 132 | -{ | |
| 133 | - uint32_t i; | |
| 134 | - uint16_t crc = 0xFFFF; | |
| 135 | - int odd; | |
| 136 | - | |
| 137 | - odd = count & 1; | |
| 138 | - count &= ~1; | |
| 139 | - for (i = 0; i != count; i++) { | |
| 140 | - crc = nvram_crc_update(crc, nvram_get_word(nvram, start + i)); | |
| 141 | - } | |
| 142 | - if (odd) { | |
| 143 | - crc = nvram_crc_update(crc, nvram_get_byte(nvram, start + i) << 8); | |
| 144 | - } | |
| 145 | - | |
| 146 | - return crc; | |
| 147 | -} | |
| 148 | - | |
| 149 | -static uint32_t nvram_set_var (m48t59_t *nvram, uint32_t addr, | |
| 150 | - const unsigned char *str) | |
| 151 | -{ | |
| 152 | - uint32_t len; | |
| 153 | - | |
| 154 | - len = strlen(str) + 1; | |
| 155 | - nvram_set_string(nvram, addr, str, len); | |
| 156 | - | |
| 157 | - return addr + len; | |
| 158 | -} | |
| 159 | - | |
| 160 | -static void nvram_finish_partition (m48t59_t *nvram, uint32_t start, | |
| 161 | - uint32_t end) | |
| 162 | -{ | |
| 163 | - unsigned int i, sum; | |
| 164 | - | |
| 165 | - // Length divided by 16 | |
| 166 | - m48t59_write(nvram, start + 2, ((end - start) >> 12) & 0xff); | |
| 167 | - m48t59_write(nvram, start + 3, ((end - start) >> 4) & 0xff); | |
| 168 | - // Checksum | |
| 169 | - sum = m48t59_read(nvram, start); | |
| 170 | - for (i = 0; i < 14; i++) { | |
| 171 | - sum += m48t59_read(nvram, start + 2 + i); | |
| 172 | - sum = (sum + ((sum & 0xff00) >> 8)) & 0xff; | |
| 173 | - } | |
| 174 | - m48t59_write(nvram, start + 1, sum & 0xff); | |
| 175 | -} | |
| 176 | - | |
| 177 | 70 | extern int nographic; |
| 178 | 71 | |
| 179 | -int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, | |
| 180 | - const unsigned char *arch, | |
| 181 | - uint32_t RAM_size, int boot_device, | |
| 182 | - uint32_t kernel_image, uint32_t kernel_size, | |
| 183 | - const char *cmdline, | |
| 184 | - uint32_t initrd_image, uint32_t initrd_size, | |
| 185 | - uint32_t NVRAM_image, | |
| 186 | - int width, int height, int depth) | |
| 72 | +static int sun4u_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size, | |
| 73 | + const unsigned char *arch, | |
| 74 | + uint32_t RAM_size, const char *boot_devices, | |
| 75 | + uint32_t kernel_image, uint32_t kernel_size, | |
| 76 | + const char *cmdline, | |
| 77 | + uint32_t initrd_image, uint32_t initrd_size, | |
| 78 | + uint32_t NVRAM_image, | |
| 79 | + int width, int height, int depth) | |
| 187 | 80 | { |
| 188 | - uint16_t crc; | |
| 189 | 81 | unsigned int i; |
| 190 | 82 | uint32_t start, end; |
| 191 | - | |
| 192 | - /* Set parameters for Open Hack'Ware BIOS */ | |
| 193 | - nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16); | |
| 194 | - nvram_set_lword(nvram, 0x10, 0x00000002); /* structure v2 */ | |
| 195 | - nvram_set_word(nvram, 0x14, NVRAM_size); | |
| 196 | - nvram_set_string(nvram, 0x20, arch, 16); | |
| 197 | - nvram_set_byte(nvram, 0x2f, nographic & 0xff); | |
| 198 | - nvram_set_lword(nvram, 0x30, RAM_size); | |
| 199 | - nvram_set_byte(nvram, 0x34, boot_device); | |
| 200 | - nvram_set_lword(nvram, 0x38, kernel_image); | |
| 201 | - nvram_set_lword(nvram, 0x3C, kernel_size); | |
| 83 | + uint8_t image[0x1ff0]; | |
| 84 | + ohwcfg_v3_t *header = (ohwcfg_v3_t *)ℑ | |
| 85 | + struct sparc_arch_cfg *sparc_header; | |
| 86 | + struct OpenBIOS_nvpart_v1 *part_header; | |
| 87 | + | |
| 88 | + memset(image, '\0', sizeof(image)); | |
| 89 | + | |
| 90 | + // Try to match PPC NVRAM | |
| 91 | + strcpy(header->struct_ident, "QEMU_BIOS"); | |
| 92 | + header->struct_version = cpu_to_be32(3); /* structure v3 */ | |
| 93 | + | |
| 94 | + header->nvram_size = cpu_to_be16(NVRAM_size); | |
| 95 | + header->nvram_arch_ptr = cpu_to_be16(sizeof(ohwcfg_v3_t)); | |
| 96 | + header->nvram_arch_size = cpu_to_be16(sizeof(struct sparc_arch_cfg)); | |
| 97 | + strcpy(header->arch, arch); | |
| 98 | + header->nb_cpus = smp_cpus & 0xff; | |
| 99 | + header->RAM0_base = 0; | |
| 100 | + header->RAM0_size = cpu_to_be64((uint64_t)RAM_size); | |
| 101 | + strcpy(header->boot_devices, boot_devices); | |
| 102 | + header->nboot_devices = strlen(boot_devices) & 0xff; | |
| 103 | + header->kernel_image = cpu_to_be64((uint64_t)kernel_image); | |
| 104 | + header->kernel_size = cpu_to_be64((uint64_t)kernel_size); | |
| 202 | 105 | if (cmdline) { |
| 203 | - /* XXX: put the cmdline in NVRAM too ? */ | |
| 204 | 106 | strcpy(phys_ram_base + CMDLINE_ADDR, cmdline); |
| 205 | - nvram_set_lword(nvram, 0x40, CMDLINE_ADDR); | |
| 206 | - nvram_set_lword(nvram, 0x44, strlen(cmdline)); | |
| 207 | - } else { | |
| 208 | - nvram_set_lword(nvram, 0x40, 0); | |
| 209 | - nvram_set_lword(nvram, 0x44, 0); | |
| 107 | + header->cmdline = cpu_to_be64((uint64_t)CMDLINE_ADDR); | |
| 108 | + header->cmdline_size = cpu_to_be64((uint64_t)strlen(cmdline)); | |
| 210 | 109 | } |
| 211 | - nvram_set_lword(nvram, 0x48, initrd_image); | |
| 212 | - nvram_set_lword(nvram, 0x4C, initrd_size); | |
| 213 | - nvram_set_lword(nvram, 0x50, NVRAM_image); | |
| 110 | + header->initrd_image = cpu_to_be64((uint64_t)initrd_image); | |
| 111 | + header->initrd_size = cpu_to_be64((uint64_t)initrd_size); | |
| 112 | + header->NVRAM_image = cpu_to_be64((uint64_t)NVRAM_image); | |
| 113 | + | |
| 114 | + header->width = cpu_to_be16(width); | |
| 115 | + header->height = cpu_to_be16(height); | |
| 116 | + header->depth = cpu_to_be16(depth); | |
| 117 | + if (nographic) | |
| 118 | + header->graphic_flags = cpu_to_be16(OHW_GF_NOGRAPHICS); | |
| 214 | 119 | |
| 215 | - nvram_set_word(nvram, 0x54, width); | |
| 216 | - nvram_set_word(nvram, 0x56, height); | |
| 217 | - nvram_set_word(nvram, 0x58, depth); | |
| 218 | - crc = nvram_compute_crc(nvram, 0x00, 0xF8); | |
| 219 | - nvram_set_word(nvram, 0xFC, crc); | |
| 120 | + header->crc = cpu_to_be16(OHW_compute_crc(header, 0x00, 0xF8)); | |
| 121 | + | |
| 122 | + // Architecture specific header | |
| 123 | + start = sizeof(ohwcfg_v3_t); | |
| 124 | + sparc_header = (struct sparc_arch_cfg *)&image[start]; | |
| 125 | + sparc_header->valid = 0; | |
| 126 | + start += sizeof(struct sparc_arch_cfg); | |
| 220 | 127 | |
| 221 | 128 | // OpenBIOS nvram variables |
| 222 | 129 | // Variable partition |
| 223 | - start = 256; | |
| 224 | - m48t59_write(nvram, start, 0x70); | |
| 225 | - nvram_set_string(nvram, start + 4, "system", 12); | |
| 130 | + part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | |
| 131 | + part_header->signature = OPENBIOS_PART_SYSTEM; | |
| 132 | + strcpy(part_header->name, "system"); | |
| 226 | 133 | |
| 227 | - end = start + 16; | |
| 134 | + end = start + sizeof(struct OpenBIOS_nvpart_v1); | |
| 228 | 135 | for (i = 0; i < nb_prom_envs; i++) |
| 229 | - end = nvram_set_var(nvram, end, prom_envs[i]); | |
| 136 | + end = OpenBIOS_set_var(image, end, prom_envs[i]); | |
| 137 | + | |
| 138 | + // End marker | |
| 139 | + image[end++] = '\0'; | |
| 230 | 140 | |
| 231 | - m48t59_write(nvram, end++ , 0); | |
| 232 | 141 | end = start + ((end - start + 15) & ~15); |
| 233 | - nvram_finish_partition(nvram, start, end); | |
| 142 | + OpenBIOS_finish_partition(part_header, end - start); | |
| 234 | 143 | |
| 235 | 144 | // free partition |
| 236 | 145 | start = end; |
| 237 | - m48t59_write(nvram, start, 0x7f); | |
| 238 | - nvram_set_string(nvram, start + 4, "free", 12); | |
| 146 | + part_header = (struct OpenBIOS_nvpart_v1 *)&image[start]; | |
| 147 | + part_header->signature = OPENBIOS_PART_FREE; | |
| 148 | + strcpy(part_header->name, "free"); | |
| 239 | 149 | |
| 240 | 150 | end = 0x1fd0; |
| 241 | - nvram_finish_partition(nvram, start, end); | |
| 151 | + OpenBIOS_finish_partition(part_header, end - start); | |
| 152 | + | |
| 153 | + for (i = 0; i < sizeof(image); i++) | |
| 154 | + m48t59_write(nvram, i, image[i]); | |
| 242 | 155 | |
| 243 | 156 | return 0; |
| 244 | 157 | } |
| ... | ... | @@ -306,7 +219,7 @@ static const int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 }; |
| 306 | 219 | static fdctrl_t *floppy_controller; |
| 307 | 220 | |
| 308 | 221 | /* Sun4u hardware initialisation */ |
| 309 | -static void sun4u_init(int ram_size, int vga_ram_size, const char *boot_device, | |
| 222 | +static void sun4u_init(int ram_size, int vga_ram_size, const char *boot_devices, | |
| 310 | 223 | DisplayState *ds, const char **fd_filename, int snapshot, |
| 311 | 224 | const char *kernel_filename, const char *kernel_cmdline, |
| 312 | 225 | const char *initrd_filename, const char *cpu_model) |
| ... | ... | @@ -428,7 +341,7 @@ static void sun4u_init(int ram_size, int vga_ram_size, const char *boot_device, |
| 428 | 341 | i8042_init(NULL/*1*/, NULL/*12*/, 0x60); |
| 429 | 342 | floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table); |
| 430 | 343 | nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59); |
| 431 | - sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device[0], | |
| 344 | + sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_devices, | |
| 432 | 345 | KERNEL_LOAD_ADDR, kernel_size, |
| 433 | 346 | kernel_cmdline, |
| 434 | 347 | INITRD_LOAD_ADDR, initrd_size, | ... | ... |