1 # This script generates an appropriate hardware.h file for Nios II Linux based
2 # on information within the target hardware's system.ptf file. This script
3 # outputs everything to stdout.
7 # [SOPC Builder]$ perl gen_hardware.h.pl <target cpu> <exec location> \
19 if (scalar (@ARGV) != 3) {
20 print STDERR
"ERROR: Invalid number of parameters.\n";
21 print ("#error Invalid number of parameters.\n");
24 $target_cpu = $ARGV[0];
25 $exec_location = $ARGV[1];
26 $upload_location = $ARGV[2];
32 my $system = SystemPTF
->new;
34 print STDERR
"ERROR: Specified file is not a SYSTEM ptf file.\n";
35 print ("#error Specified file is not a SYSTEM ptf file.\n");
40 # print header for nios2_system.h
43 #ifndef __NIOS2_SYSTEM_H__
44 #define __NIOS2_SYSTEM_H__
47 * This file contains hardware information about the target platform.
48 * The nios2_system.h file is being phased out and will be removed in a
51 * All base addresses for non memory devices have their high bit turned on to
54 * This file is automatically generated. Do not modify.
60 # generate contents for nios2_system.h
62 my $result; # dummy variable
63 my $cpu = $system->getCPU ($target_cpu);
65 print STDERR
"ERROR: $target_cpu is not a valid CPU in system: " . $system->getName () . ".\n";
66 print "#error $target_cpu is not a valid CPU in system: " . $system->getName () . ".\n";
70 my $exec_module = $system->getModule ($exec_location);
72 print STDERR
"ERROR: $exec_location is not a valid module in the system: " . $system->getName() . ".\n";
73 print "#error $exec_location is not a valid module in system: " . $system->getName () . ".\n";
77 my $upload_module = $system->getModule ($upload_location);
78 if (! $upload_module) {
79 print STDERR
"ERROR: $upload_location is not a valid module in the system: " . $system->getName() . ".\n";
80 print "#error $upload_location is not a valid module in system: " . $system->getName () . ".\n";
85 my @found_classes_order;
87 # the SYSPTF environment variable is set by kernel build process.
88 if ($ENV{SYSPTF
} ne "") {
89 print "/* Input System: " . $ENV{SYSPTF
} . ":" . $system->getName () . " */\n";
91 print "/* Input System: " . $system->getName () . " */\n";
93 print "/* Target CPU: " . $target_cpu . " */\n";
97 print <<ENDOFCONSTANTS;
98 /* Nios II Constants */
99 #define NIOS2_STATUS_PIE_MSK 0x1
100 #define NIOS2_STATUS_PIE_OFST 0
101 #define NIOS2_STATUS_U_MSK 0x2
102 #define NIOS2_STATUS_U_OFST 1
108 print " * Outputting basic values from system.ptf.\n";
112 # Start outputing information about each module.
114 my @module_names = $system->getSlaveModules ($target_cpu);
115 foreach my $module_name (@module_names) {
116 my $module = $system->getModule ($module_name);
117 my $module_class = $module->getClass ();
118 my @module_ports = $module->getPorts ();
120 my $text_printed = 0;
123 # $output .= "/* $module_name (of type $module_class) */\n";
125 if (! exists $found_classes{$module_class}) {
126 push @found_classes_order, $module_class;
128 push @
{$found_classes{$module_class}}, $module_name;
130 if (! $module->isMemoryDevice () && ! $module->isCustomInstruction ()) {
131 # turn on high bit for base address
135 if (scalar (@module_ports) == 1) {
140 # base address information
141 $base_address = $module->getBaseAddress ();
143 $output .= sprintf ("#define na_%-50s %#010x\n",
144 ($module_name, hex ($base_address) | $mask));
147 if ($module->isMemoryDevice()) {
148 # output size and end address
149 $mem_size = $module->getSize();
150 $output .= sprintf ("#define na_%-50s %#010x\n",
151 ($module_name . "_size", hex ($mem_size)));
152 $mem_end = hex ($mem_size) + hex($base_address);
153 $output .= sprintf ("#define na_%-50s %#010x\n",
154 ($module_name . "_end", $mem_end));
160 $result = $module->getIRQ ();
161 if (defined ($result)) {
162 $output .= sprintf ("#define na_%-30s %30s\n",
163 ($module_name . "_irq", $result));
168 # if device has multiple ports
169 foreach my $port_name (@module_ports) {
170 # base address information
171 $result = $module->getBaseAddress ($port_name);
173 $output .= sprintf ("#define na_%-50s %#010x\n",
174 ($module_name . "_" . $port_name, hex ($result) | $mask));
179 $result = $module->getIRQ ($port_name);
180 if (defined ($result)) {
181 $output .= sprintf ("#define na_%-30s %30s\n",
182 ($module_name . "_" . $port_name . "_irq", $result));
188 if ($text_printed == 1) {
197 # Handle special cases through customized perl scripts
199 foreach my $class_name (@found_classes_order) {
202 foreach my $dir (@INC) {
203 if (-e
"$dir/nios2_system.h/$class_name.pm") {
204 print "/* Executing ...scripts/nios2_system.h/$class_name.pm */\n";
205 $code .= "require \"$dir/nios2_system.h/BasicModule.pm\";";
206 $code .= "require \"$dir/nios2_system.h/$class_name.pm\";";
207 $code .= $class_name . "::run(\$system, \@{\$found_classes{\$class_name}});";
210 print "#warning Could not execute ...scripts/nios2_system.h/$class_name.pm\n";
211 print "#warning Error message is stored in nios2_system.h:\n";
215 print STDERR
"Could not execute ...scripts/nios2_system.h/$class_name.pm\n";
216 print STDERR
"Error message follows:\n";
225 # Write out system information
228 print " * Basic System Information\n";
231 $result = $cpu->getWSAAssignment ('cache_icache_size');
232 printf ("#define %-53s %10d\n", ("nasys_icache_size", $result));
234 $result = $cpu->getConstant ('nasys_icache_line_size');
235 printf ("#define %-53s %10d\n", ("nasys_icache_line_size", $result));
237 $result = $cpu->getWSAAssignment ('cache_dcache_size');
238 printf ("#define %-53s %10d\n", ("nasys_dcache_size", $result));
240 $result = $cpu->getConstant ('nasys_dcache_line_size');
241 printf ("#define %-53s %10d\n", ("nasys_dcache_line_size", $result));
245 printf ("#define %-33s %30s\n",
246 ("nasys_program_mem", "na_${exec_location}"));
247 printf ("#define %-33s %30s\n",
248 ("nasys_program_mem_size", "na_${exec_location}_size"));
249 printf ("#define %-33s %30s\n",
250 ("nasys_program_mem_end", "na_${exec_location}_end"));
254 if ($upload_location eq "flash_kernel") {
256 print ("/* Redefinition of CFI flash memory unecessary */\n");
258 my $module = $system->getModule ("flash_kernel");
260 # there is a conflicting module in the system, error.
261 print STDERR
"Error, a SOPC module named flash_kernel already exists but is not the upload location.\n";
262 print "#error The module name \"flash_kernel\" already exists but isn't the upload location.\n";
263 print "#error This will break the kernel.\n";
264 print "#error Please rename the module to something else in SOPC Builder.\n\n";
268 print (" * Redefining upload location ($upload_location) to flash_kernel.\n");
270 # undefine the original module names and re-define them here.
271 print ("#undef na_${upload_location}\n");
272 print ("#undef na_${upload_location}_size\n");
273 print ("#undef na_${upload_location}_end\n");
275 my $base_address = $upload_module->getBaseAddress ();
276 printf ("#define %-33s %30s\n",
277 ("na_flash_kernel", $base_address));
279 my $mem_size = $upload_module->getSize();
280 printf ("#define %-33s %30s\n",
281 ("na_flash_kernel_size", $mem_size));
283 my $mem_end = hex ($base_address) + hex ($mem_size);
284 printf ("#define %-53s %#010x\n",
285 ("na_flash_kernel_end", $mem_end));
291 printf ("#define %-33s %30s\n",
292 ("nasys_clock_freq", $system->getClockFreq()));
293 printf ("#define %-33s %30s\n",
294 ("nasys_clock_freq_1000", int ($system->getClockFreq()) / 1000));
297 my ($reset_location, $reset_offset) = $cpu->getResetLocationOffset();
298 my ($reset_module_name, $reset_port_name) = ($reset_location =~ /(.*)\/(.*)/);
299 my $reset_module = $system->getModule ($reset_module_name);
300 my $reset_address = $reset_module->getBaseAddress ($reset_port_name);
302 $reset_address = hex ($reset_address) + hex ($reset_offset);
303 printf ("#define %-53s %#010x\n",
304 ("CPU_RESET_ADDRESS", $reset_address));
310 # print footer for nios2_system.h
313 #endif /* __NIOS2_SYSTEM_H__ */