Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / t1_fpga / src / xilinx / tools / make_prom / make_prom.c
CommitLineData
920dae64
AT
1/*
2* ========== Copyright Header Begin ==========================================
3*
4* OpenSPARC T2 Processor File: make_prom.c
5* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
7*
8* The above named program is free software; you can redistribute it and/or
9* modify it under the terms of the GNU General Public
10* License version 2 as published by the Free Software Foundation.
11*
12* The above named program is distributed in the hope that it will be
13* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public
18* License along with this work; if not, write to the Free Software
19* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20*
21* ========== Copyright Header End ============================================
22*/
23/*
24 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28#include <sys/types.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <strings.h>
32#include <errno.h>
33#include <inttypes.h>
34
35#include <unistd.h>
36#include <fcntl.h>
37#include <sys/stat.h>
38#include <sys/mman.h>
39
40
41#include "xilinx_t1_system_config.h"
42
43
44/*
45 * This program is used to create prom.bin from the components.
46 */
47
48
49static char *prom_filename = "";
50
51
52struct file_info {
53 char *name;
54 size_t prom_file_offset;
55 size_t max_file_size;
56};
57
58
59#define F_RESET 0
60#define F_Q 1
61#define F_OPENBOOT 2
62#define F_GUEST_MD 3
63#define F_HV_MD 4
64#define F_NVRAM 5
65#define F_MAX 6
66
67
68
69struct file_info files[F_MAX] = {
70 { "reset.bin", T1_FPGA_PROM_RESET_OFFSET, T1_FPGA_PROM_MAX_RESET_SIZE },
71 { "q.bin", T1_FPGA_PROM_HV_OFFSET, T1_FPGA_PROM_MAX_HV_SIZE },
72 { "openboot.bin", T1_FPGA_PROM_OPENBOOT_OFFSET, T1_FPGA_PROM_MAX_OPENBOOT_SIZE },
73 { "guest.md", T1_FPGA_PROM_GUEST_MD_OFFSET, T1_FPGA_PROM_MAX_GUEST_MD_SIZE },
74 { "hv.md", T1_FPGA_PROM_HV_MD_OFFSET, T1_FPGA_PROM_MAX_HV_MD_SIZE },
75 { "nvram.bin", T1_FPGA_PROM_NVRAM_OFFSET, T1_FPGA_PROM_MAX_NVRAM_SIZE }
76};
77
78
79static void
80cleanup_and_exit(int status)
81{
82 unlink(prom_filename);
83 exit(status);
84}
85
86
87/*
88 * Always reads "nbyte" bytes unless end of file encountered.
89 */
90
91static ssize_t
92read_all(int ifd, char *buf, size_t nbyte, const char *filename)
93{
94 size_t rem_bytes, bytes_read;
95 ssize_t read_result;
96
97 bytes_read = 0;
98 rem_bytes = nbyte;
99
100 while (rem_bytes) {
101 read_result = read(ifd, &buf[bytes_read], rem_bytes);
102 if (read_result < 0) {
103 perror("ERROR: read ");
104 fprintf(stderr, "ERROR: Couldn't read file \"%s\" \n", filename);
105 cleanup_and_exit(EXIT_FAILURE);
106 }
107 if (read_result == 0) {
108 return bytes_read;
109 }
110
111 rem_bytes -= read_result;
112 bytes_read += read_result;
113 }
114
115 return bytes_read;
116}
117
118static size_t
119get_file_size(const char *filename)
120{
121 struct stat stat_buf;
122
123 if (stat(filename, &stat_buf) < 0) {
124 perror("ERROR: stat");
125 fprintf(stderr, "ERROR: Couldn't stat file \"%s\" \n", filename);
126 cleanup_and_exit(EXIT_FAILURE);
127 }
128
129 return stat_buf.st_size;
130}
131
132static void
133read_file(char *filename, char *buf, size_t buf_size)
134{
135 int fd;
136 size_t file_size;
137
138 struct stat stat_buf;
139
140 fd = open(filename, O_RDONLY);
141 if (fd < 0) {
142 perror("ERROR: open");
143 printf("ERROR: error opening file \"%s\" for reading. \n", filename);
144 cleanup_and_exit(EXIT_FAILURE);
145 }
146
147 file_size = get_file_size(filename);
148
149 if (file_size > buf_size) {
150 fprintf(stderr, "ERROR: filename %s: file_size 0x%" PRIx64 " is larger than allocated space 0x%" PRIx64 " \n",
151 filename, (uint64_t) file_size, (uint64_t) buf_size);
152 cleanup_and_exit(EXIT_FAILURE);
153 }
154
155 read_all(fd, buf, file_size, filename);
156 close(fd);
157
158 return;
159}
160
161void
162print_help_and_exit(const char *progname)
163{
164 printf("%s \n", progname);
165 printf(" -g <filename> # guest machine description file \n");
166 printf(" -h # print this help \n");
167 printf(" -H <filename> # hypervisor machine description file \n");
168 printf(" -n <filename> # nvram file \n");
169 printf(" -o <filename> # openboot file \n");
170 printf(" -p <filename> # prom file \n");
171 printf(" -r <filename> # reset file \n");
172 exit(1);
173}
174
175int
176process_options(int argc, char *argv[])
177{
178 int lib_result;
179
180 while ((lib_result = getopt(argc, argv, "g:H:o:p:r:h")) != -1) {
181 switch (lib_result) {
182 case 'g':
183 files[F_GUEST_MD].name = strdup(optarg);
184 break;
185 case 'H':
186 files[F_HV_MD].name = strdup(optarg);
187 break;
188 case 'o':
189 files[F_OPENBOOT].name = strdup(optarg);
190 break;
191 case 'p':
192 prom_filename = strdup(optarg);
193 break;
194 case 'n':
195 files[F_NVRAM].name = strdup(optarg);
196 break;
197 case 'r':
198 files[F_RESET].name = strdup(optarg);
199 break;
200 case 'h':
201 print_help_and_exit(argv[0]);
202 /* NOT REACHED */
203 break;
204 default:
205 print_help_and_exit(argv[0]);
206 /* NOT REACHED */
207 break;
208 }
209 }
210
211 return 0;
212}
213
214int
215main(int argc, char *argv[])
216{
217 int fd;
218 off_t prom_file_offset;
219
220 size_t bytes_written;
221 off_t lseek_result;
222
223 char buf[1];
224
225
226 process_options(argc, argv);
227
228 if (prom_filename[0] == 0) {
229 fprintf(stderr, "ERROR: prom filename not specified \n");
230 cleanup_and_exit(EXIT_FAILURE);
231 }
232
233 fd = open(prom_filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
234 if (fd < 0) {
235 perror("ERROR: open");
236 fprintf(stderr, "ERROR: Couldn't open/creat prom file \"%s\" for reading/writing \n", prom_filename);
237 cleanup_and_exit(EXIT_FAILURE);
238 }
239
240 prom_file_offset = T1_FPGA_PROM_BIN_FILE_SIZE - 1;
241 lseek_result = lseek(fd, prom_file_offset, SEEK_SET);
242 if (lseek_result == (off_t) -1) {
243 perror("ERROR: lseek");
244 fprintf(stderr, "ERROR: lseek failed trying to set file pointer to 0x%" PRIx64 " \n", (uint64_t)prom_file_offset);
245 cleanup_and_exit(EXIT_FAILURE);
246 }
247
248 buf[0] = 0;
249 bytes_written = write(fd, buf, 1);
250 if (bytes_written < 0) {
251 perror("ERROR: write ");
252 fprintf(stderr, "ERROR: Couldn't write to prom file \"%s\" \n", prom_filename);
253 cleanup_and_exit(EXIT_FAILURE);
254 }
255
256 caddr_t addr = mmap(0, T1_FPGA_PROM_BIN_FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
257 if (addr == MAP_FAILED) {
258 perror("ERROR: mmap");
259 cleanup_and_exit(EXIT_FAILURE);
260 }
261 memset(addr, 0, T1_FPGA_PROM_BIN_FILE_SIZE);
262
263 for (int i=0; i<F_MAX; i++) {
264 read_file(files[i].name, (addr + files[i].prom_file_offset), files[i].max_file_size);
265 }
266
267 munmap(addr, T1_FPGA_PROM_BIN_FILE_SIZE);
268
269 close(fd);
270
271 return 0;
272}
273
274