A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd
at master 2692 lines 99 kB view raw
1/*************************************************************************** 2 * __________ __ ___. 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 * \/ \/ \/ \/ \/ 8 * $Id$ 9 * 10 * Copyright (C) 2015 by Amaury Pouly 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 2 15 * of the License, or (at your option) any later version. 16 * 17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 18 * KIND, either express or implied. 19 * 20 ****************************************************************************/ 21#include "soc_desc.hpp" 22#include <cstdio> 23#include <cstdlib> 24#include <algorithm> 25#include <map> 26#include <sstream> 27#include <sys/stat.h> 28#include <sys/types.h> 29#include <getopt.h> 30#include <fstream> 31#include <set> 32 33using namespace soc_desc; 34 35#define HEADERGEN_VERSION "3.0.0" 36 37/** 38 * Useful stuff 39 */ 40 41std::string tolower(const std::string s) 42{ 43 std::string res = s; 44 for(size_t i = 0; i < s.size(); i++) 45 res[i] = ::tolower(res[i]); 46 return res; 47} 48 49std::string toupper(const std::string& s) 50{ 51 std::string res = s; 52 for(size_t i = 0; i < s.size(); i++) 53 res[i] = ::toupper(res[i]); 54 return res; 55} 56 57template< typename T > 58std::string to_str(const T& v) 59{ 60 std::ostringstream oss; 61 oss << v; 62 return oss.str(); 63} 64 65template< typename T > 66std::string to_hex(const T& v) 67{ 68 std::ostringstream oss; 69 oss << "0x" << std::hex << v; 70 return oss.str(); 71} 72 73std::string strsubst(const std::string& str, const std::string& pattern, 74 const std::string& subst) 75{ 76 std::string res = str; 77 size_t pos = 0; 78 while((pos = res.find(pattern, pos)) != std::string::npos) 79 { 80 res.replace(pos, pattern.size(), subst); 81 pos += subst.size(); 82 } 83 return res; 84} 85 86void print_context(const error_context_t& ctx) 87{ 88 for(size_t j = 0; j < ctx.count(); j++) 89 { 90 err_t e = ctx.get(j); 91 switch(e.level()) 92 { 93 case err_t::INFO: printf("[INFO]"); break; 94 case err_t::WARNING: printf("[WARN]"); break; 95 case err_t::FATAL: printf("[FATAL]"); break; 96 default: printf("[UNK]"); break; 97 } 98 if(e.location().size() != 0) 99 printf(" %s:", e.location().c_str()); 100 printf(" %s\n", e.message().c_str()); 101 } 102} 103 104void print_inst(node_inst_t inst, bool end = true) 105{ 106 if(!inst.is_root()) 107 { 108 print_inst(inst.parent(), false); 109 printf(".%s", inst.name().c_str()); 110 if(inst.is_indexed()) 111 printf("[%u]", (unsigned)inst.index()); 112 } 113 else 114 { 115 printf("%s", inst.soc().get()->name.c_str()); 116 } 117 if(end) 118 printf("\n"); 119} 120 121void create_dir(const std::string& path) 122{ 123 mkdir(path.c_str(), 0755); 124} 125 126void create_alldir(const std::string& prefix, const std::string& path) 127{ 128 size_t p = path.find('/'); 129 if(p == std::string::npos) 130 return; 131 create_dir(prefix + "/" + path.substr(0, p)); 132 create_alldir(prefix + "/" + path.substr(0, p), path.substr(p + 1)); 133} 134 135/** 136 * Printer utils 137 */ 138 139struct limited_column_context_t 140{ 141 limited_column_context_t(size_t nr_col = 80) 142 :m_nr_col(nr_col), m_prevent_wordcut(true) {} 143 void set_prefix(const std::string& prefix) { m_prefix = prefix; } 144 void add(const std::string& text) 145 { 146 for(size_t i = 0; i < text.size();) 147 { 148 size_t offset = 0; 149 if(m_cur_line.size() == 0) 150 m_cur_line = m_prefix; 151 size_t len = std::min(text.size() - i, m_nr_col - m_cur_line.size()); 152 // prevent word cut 153 if(m_prevent_wordcut && !isspace(text[i + len - 1]) && 154 i + len < text.size() && !isspace(text[i + len])) 155 { 156 size_t pos = text.find_last_of(" \t\n\v\r\f", i + len - 1); 157 if(pos == std::string::npos || pos < i) 158 len = 0; 159 else 160 len = pos - i + 1; 161 } 162 size_t pos = text.find('\n', i); 163 if(pos != std::string::npos && pos <= i + len) 164 { 165 offset = 1; 166 len = pos - i; 167 } 168 m_cur_line += text.substr(i, len); 169 // len == 0 means we need a new line 170 if(m_cur_line.size() == m_nr_col || len == 0) 171 { 172 m_lines.push_back(m_cur_line); 173 m_cur_line = ""; 174 } 175 i += len + offset; 176 } 177 } 178 179 std::ostream& print(std::ostream& oss) 180 { 181 for(size_t i = 0; i < m_lines.size(); i++) 182 oss << m_lines[i] << "\n"; 183 if(m_cur_line.size() != 0) 184 oss << m_cur_line << "\n"; 185 return oss; 186 } 187 188 std::string str() 189 { 190 std::ostringstream oss; 191 print(oss); 192 return oss.str(); 193 } 194 195 std::vector< std::string > m_lines; 196 std::string m_cur_line; 197 std::string m_prefix; 198 size_t m_nr_col; 199 bool m_prevent_wordcut; 200}; 201 202struct define_align_context_t 203{ 204 define_align_context_t():m_max_name(0) {} 205 void add(const std::string& name, const std::string& val) 206 { 207 m_lines.push_back(std::make_pair(name, val)); 208 m_max_name = std::max(m_max_name, name.size()); 209 } 210 211 void add_raw(const std::string& line) 212 { 213 m_lines.push_back(std::make_pair("", line)); 214 } 215 216 std::ostream& print(std::ostream& oss) 217 { 218 std::string define = "#define "; 219 size_t align = define.size() + m_max_name + 1; 220 align = ((align + 3) / 4) * 4; 221 222 for(size_t i = 0; i < m_lines.size(); i++) 223 { 224 std::string name = m_lines[i].first; 225 // raw entry ? 226 if(name.size() != 0) 227 { 228 name.insert(name.end(), align - define.size() - name.size(), ' '); 229 oss << define << name << m_lines[i].second << "\n"; 230 } 231 else 232 oss << m_lines[i].second; 233 } 234 return oss; 235 } 236 237 size_t m_max_name; 238 std::vector< std::pair< std::string, std::string > > m_lines; 239}; 240 241limited_column_context_t print_description(const std::string& desc, const std::string& prefix) 242{ 243 limited_column_context_t ctx; 244 if(desc.size() == 0) 245 return ctx; 246 ctx.set_prefix(prefix); 247 ctx.add(desc); 248 return ctx; 249} 250 251void print_copyright(std::ostream& fout, const std::vector< soc_ref_t >& socs) 252{ 253 fout << "\ 254/***************************************************************************\n\ 255 * __________ __ ___.\n\ 256 * Open \\______ \\ ____ ____ | | _\\_ |__ _______ ___\n\ 257 * Source | _// _ \\_/ ___\\| |/ /| __ \\ / _ \\ \\/ /\n\ 258 * Jukebox | | ( <_> ) \\___| < | \\_\\ ( <_> > < <\n\ 259 * Firmware |____|_ /\\____/ \\___ >__|_ \\|___ /\\____/__/\\_ \\\n\ 260 * \\/ \\/ \\/ \\/ \\/\n\ 261 * This file was automatically generated by headergen, DO NOT EDIT it.\n\ 262 * headergen version: " HEADERGEN_VERSION "\n"; 263 for(size_t i = 0; i < socs.size(); i++) 264 { 265 soc_t& s = *socs[i].get(); 266 if(!s.version.empty()) 267 fout << " * " << s.name << " version: " << s.version << "\n"; 268 if(!s.author.empty()) 269 { 270 fout << " * " << s.name << " authors:"; 271 for(size_t j = 0; j < s.author.size(); j++) 272 { 273 if(j != 0) 274 fout << ","; 275 fout << " " << s.author[j]; 276 } 277 fout << "\n"; 278 } 279 } 280 fout << "\ 281 *\n\ 282 * Copyright (C) 2015 by the authors\n\ 283 *\n\ 284 * This program is free software; you can redistribute it and/or\n\ 285 * modify it under the terms of the GNU General Public License\n\ 286 * as published by the Free Software Foundation; either version 2\n\ 287 * of the License, or (at your option) any later version.\n\ 288 *\n\ 289 * This software is distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY\n\ 290 * KIND, either express or implied.\n\ 291 *\n\ 292 ****************************************************************************/\n"; 293} 294 295void print_guard(std::ostream& fout, const std::string& guard, bool begin) 296{ 297 if(begin) 298 { 299 fout << "#ifndef " << guard << "\n"; 300 fout << "#define " << guard << "\n"; 301 } 302 else 303 fout << "\n#endif /* " << guard << "*/\n"; 304} 305 306/** 307 * Generator interface 308 */ 309 310class abstract_generator 311{ 312public: 313 /// set output directory (default is current directory) 314 void set_output_dir(const std::string& dir); 315 /// add a SoC to the list 316 void add_soc(const soc_t& soc); 317 /// generate headers, returns true on success 318 virtual bool generate(error_context_t& ctx) = 0; 319protected: 320 std::vector< soc_t > m_soc; /// list of socs 321 std::string m_outdir; /// output directory path 322}; 323 324void abstract_generator::set_output_dir(const std::string& dir) 325{ 326 m_outdir = dir; 327} 328 329void abstract_generator::add_soc(const soc_t& soc) 330{ 331 m_soc.push_back(soc); 332} 333 334/** 335 * Common Generator 336 * 337 * This generator is an abstract class which can generate register headers while 338 * giving the user a lot of control on how the macros are named and generated. 339 * 340 * The first thing the generator will want to know is whether you want to generate 341 * selector headers or not. Selector headers are used when generating headers from 342 * several SoCs: the selector will include the right header based on some user-defined 343 * logic. For example, imagine you have two socs vsoc1000 and vsoc2000, you could 344 * generate the following files and directories: 345 * 346 * regs/ 347 * regs-vsoc.h [selector] 348 * vsoc1000/ 349 * regs-vsoc.h [vsoc1000 header] 350 * vsoc2000/ 351 * regs-vsoc.h [vsoc2000 header] 352 * 353 * The generator will call has_selectors() to determine if it should generate 354 * selector files or not. If it returns true, it will call selector_soc_dir() 355 * for each of the socs to know in which subdirectory it should include the headers. 356 * The generator will create one macro per soc, which name is given by 357 * selector_soc_macro() and it will finally include the select header YOU will 358 * have to write, which name is given by selector_include_header() 359 * The selector file will typically look like this: 360 * 361 * [regs-vsoc.h] 362 * #define VSOC1000_INCLUDE "vsoc1000/regs-vsoc.h" // returned by selector_soc_macro(vsoc1000) 363 * #define VSOC2000_INCLUDE "vsoc2000/regs-vsoc.h" // returned by selector_soc_macro(vsoc2000) 364 * #include "regs-select.h" // returned by selector_include_header() 365 * 366 * NOTE: it may happen that some header only exists in some soc (for example 367 * in vsoc2000 but not in vsoc1000), in this case the macros will only be 368 * generated for the socs in which it exists. 369 * NOTE: and this is *VERY* important: the register selector file MUST NOT 370 * be protected by include guards since it will included several times, once 371 * for each register file. 372 * 373 * The generator will create one set of files per soc. For each register, it 374 * will call register_header() to determine in which file you want the register 375 * to be put. You can put everything in one file, or one register per file, 376 * that's entirely up to you. Here is an example: 377 * 378 * register_header(vsoc1000.cpu.ctrl) -> "regs-cpu.h" 379 * register_header(vsoc1000.cpu.reset) -> "regs-cpu.h" 380 * register_header(vsoc1000.cop.ctrl) -> "regs-cop.h" 381 * register_header(vsoc1000.cop.magic) -> "regs-magic.h" 382 * 383 * regs-cpu.h: 384 * vsoc1000.cpu.ctrl 385 * vsoc1000.cpu.reset 386 * regs-cop.h: 387 * vsoc1000.cop.ctrl 388 * regs-magic.h 389 * vsoc1000.cop.magic 390 * 391 * Once the list of register files is determine, it will begin generating each 392 * file. A register header is always protected from double inclusion by an 393 * include guard. You can tweak the name by redefining header_include_guard() 394 * or keep the default behaviour which generates something like this: 395 * 396 * #ifndef __HEADERGEN_REGS_CPU_H__ 397 * #define __HEADERGEN_REGS_CPU_H__ 398 * ... 399 * #endif 400 * 401 * NOTE: the tool will also generate a copyright header which contains the Rockbox 402 * logo, a list of soc names and version, and authors in the description file. 403 * This part cannot be customised at the moment. 404 * 405 * In order to list all registers, the generator will recursively enumerate all 406 * nodes and instances. When a instance is of RANGE type, the generator can generate 407 * two types of macros: 408 * - one for each instance 409 * - one with an index parameter 410 * The generator will ask you if you want to generate one for each instance by 411 * calling register_flag(RF_GENERATE_ALL_INST) and if you want to generate a 412 * parametrized one by calling register_flag(RF_GENERATE_PARAM_INST). You can 413 * generate either one or both (or none). 414 * 415 * register_flag(vsoc.int.enable, RF_GENERATE_ALL_INST) -> true 416 * => will generate vsoc.int.enable[1], vsoc.int.enable[2], ... 417 * register_flag(vsoc.int.enable, RF_GENERATE_PARAM_INST) -> true 418 * => will generate vsoc.int.enable[n] 419 * 420 * This process will give a list of pseudo-instances: these are register instances 421 * where some ranges have a given index and some ranges are parametric. The generator 422 * will create one set of macro per pseudo-instance. The exact list of macros 423 * generated is the following: 424 * - ADDR: this macro will contain the address of the register (possibly parametrized) 425 * - TYPE: this macro will contain the type of the register (width, access) 426 * - NAME: this macro expands to the name of the register (useful for fields and other variants) 427 * - INDEX: this macro expands to the index of the register (or empty is not indexed) 428 * - VAR: this macros expands to a fake variable that can be read/written 429 * - for each field F: 430 * - BP: this macro contains the bit position of F 431 * - BM: this macro contains the bit mask of F 432 * - for each field enum value V: 433 * - BV: this macro contains the value of V (not shifted to the position) 434 * - BF: this macro generate the mask for a value: (((v) << pos) & mask) 435 * - BFV: same as BF but the parameter is the name of an enum value 436 * - BFM: this macro is like BF but ignores value returns mask 437 * - BFMV: like BFV but returns masks like BFM 438 * The generator will also create the following macros for each variant: 439 * - ADDR: same as ADDR but with offset 440 * - TYPE: same as TYPE but depends on variant 441 * - NAME: same as NAME (ie same fields) 442 * - INDEX: same as INDEX 443 * 444 * In order to generate the macro name, the generate relies on you providing detailled 445 * information. Given an pseudo-instance I and a macro type MT, the generator 446 * will always call type_xfix(MT) to know which prefix/suffix you want for the 447 * macro and generate names of the form: 448 * type_xfix(MT, true)basename(I)type_xfix(MT, false) 449 * The basename() functions will call inst_prefix() for each each instance on the 450 * pseudo-instance path, and then instance_name() to know the name. You can 451 * (and must) create a different name for parametrised instances. The basename 452 * looks like this for pseudo-inst i1.i2.i3....in: 453 * instance_name(i1)inst_prefix(i1.i2)instance_name(i1.i2)...inst_name(i1.i2...in) 454 * For field macros, the process is the same with an extra prefix returned by 455 * field_prefix() and you can select the field name with field_name() to obtain 456 * for example for field F in I: 457 * type_xfix(MT,true)basename(I)field_prefix()field_name(I.F)type_xfix(MT,false) 458 * For field enum macros, there is an extra prefix given by enum_prefix() 459 * and the enum name is given by enum_name() 460 * For variants, the basename is surrounded by prefix/suffix given by variant_xfix(): 461 * variant_xfix(var, true)basename(I)variant_xfix(var, false) 462 * 463 * Let's illustrate this on example 464 * type_xfix(MT_REG_ADDR, true) -> "RA_x" 465 * type_xfix(MT_REG_ADDR, false) -> "x_AR" 466 * instance_name(vsoc1000.cpu) -> "CPU" 467 * inst_prefix(vsoc1000.cpu.ctrl) -> "_" 468 * instance_name(vsoc1000.cpu.ctrl) -> "CTRL" 469 * => RA_xCPU_CTRLx_AR 470 * type_xfix(MT_FIELD_BF, true) -> "BF_" 471 * type_xfix(MT_FIELD_BF, false) -> "" 472 * field_prefix() -> "__" 473 * field_name(vsoc1000.cpu.ctrl.speed) -> "SPEED" 474 * => BF_CPU_CTRL__SPEED 475 * variant_xfix("set", true) -> "VAR_" 476 * variant_xfix("set", false) -> "_SET" 477 * => HW_VAR_CPU_CTRL_SET 478 * 479 * The generator will also create a macro header file, it will call macro_header() 480 * once to know the name of this file. 481 * The macro header contains useful macro to read, write and manipulate registers 482 * and fields. You must implement the macro_header_macro() method to let the 483 * generator know the name of each macro. Note that the macro header macros 484 * depend on the specific naming of the other macros, which are given by 485 * type_xfix() and field_prefix() most notably. The exact list of generated macros 486 * is the following: 487 * - BF_OR: field ORing (see details below) 488 * - BF_OM: mask ORing (same as BF_OR but except field value is the mask) 489 * 490 * The BF_OR macro is one of the most important and useful macro. It allows for 491 * compact ORing of register field, both for immediate values or value names. 492 * For this macro to work properly, there are constraints that the generator 493 * must satisfy. Notably, type_xfix(MT_FIELD_BF, true) == type_xfix(MT_FIELD_BFV, true) 494 * and similarly for MT_FIELD_BM 495 * The general format is as follows: 496 * 497 * BF_OR(<reg>, <f1>, <f2>, ...) expands to BF(<reg>,<f1>) | BF(<reg>,<f2>) | ... 498 * BM_OR(<reg>, <f1>, <f2>, ...) expands to BM(<reg>,<f1>) | BM(<reg>,<f2>) | ... 499 * 500 * Typical usages of this macro will be of the form: 501 * 502 * BF_OR(<reg>, <f1>(<v1>), <f2>(<v2>), <f3name>(<v3name>), ...) 503 * BM_OR(<reg>, <f1>, <f2>, <f3>, ...) 504 * 505 * 506 * Let's illustrate this on example. 507 * type_xfix(MT_FIELD_BF, true) -> "BF_" 508 * type_xfix(MT_FIELD_BFV, true) -> "BF_" 509 * type_xfix(MT_FIELD_BF, false) -> "BF_" 510 * type_xfix(MT_FIELD_BF, false) -> "_V" 511 * field_prefix() -> "__" 512 * enum_prefix() -> "___" 513 * macro_header_macro(MMM_BF_OR) -> "BF_OR" 514 * => BF_OR(<reg>, <f1>, <f2>, ...) expands to BF_<reg>__<f1> | BF_<reg>__<f2> | ... 515 * => BF_OR(CPU_CTRL, DIVIDER(1), PRIO_V(HIGH), SPEED(100)) 516 * expands to 517 * BF_CPU_CTRL__DIVIDER(1) | BF_CPU_CTRL__DIVIDER_V(HIGH) | BF_CPU_CTRL__SPEED(1000) 518 * expands to 519 * BF_CPU_CTRL__DIVIDER(1) | BF_CPU_CTRL__DIVIDER(BV_CPU_CTRL__DIVIDER___HIGH) | BF_CPU_CTRL__SPEED(1000) 520 * and so on... 521 * 522 */ 523class common_generator : public abstract_generator 524{ 525 struct pseudo_node_inst_t 526 { 527 node_inst_t inst; 528 std::vector< bool > parametric; 529 }; 530public: 531 virtual bool generate(error_context_t& ctx); 532protected: 533 /// return true to generate support macros 534 /// if false then all macros are disabled except MT_REG_ADDR, MT_REG_VAR, 535 /// and MT_FIELD_*. Also the macro header is not created 536 virtual bool has_support_macros() const = 0; 537 /// return true to generate selector files 538 virtual bool has_selectors() const = 0; 539 /// return true to generate node address and register offset macros 540 virtual bool has_offsets() const = 0; 541 /// [selector only] return the directory name for the soc 542 virtual std::string selector_soc_dir(const soc_ref_t& ref) const = 0; 543 /// [selector only] return the header to include to select betweens socs 544 virtual std::string selector_include_header() const = 0; 545 /// [selector only] return the name of the macro to emit for each soc 546 virtual std::string selector_soc_macro(const soc_ref_t& ref) const = 0; 547 /// return the relative filename in which to put the register 548 virtual std::string register_header(const node_inst_t& inst) const = 0; 549 /// return the include guard for a file (default does its best) 550 virtual std::string header_include_guard(const std::string& filename); 551 /// return the name of the macros header to generate 552 virtual std::string macro_header() const = 0; 553 /// macro from macro header 554 enum macro_name_t 555 { 556 MN_REG_READ, /// register read 557 MN_FIELD_READ, /// register's field read 558 MN_FIELD_READX, /// register value field read 559 MN_REG_WRITE, /// register write 560 MN_REG_SET, /// register set 561 MN_REG_CLEAR, /// register clear 562 MN_REG_CLEAR_SET, /// register clear then set 563 MN_FIELD_WRITE, /// register's field(s) write 564 MN_FIELD_WRITEX, /// register's field(s) write 565 MN_FIELD_OVERWRITE, /// register full write 566 MN_FIELD_SET, /// register's field(s) set 567 MN_FIELD_CLEAR, /// register's field(s) clear 568 MN_FIELD_TOG, /// register's field(s) toggle 569 MN_FIELD_CLEAR_SET, /// register's field(s) clear then set 570 MN_FIELD_OR, /// field ORing 571 MN_FIELD_OR_MASK, /// field ORing but in fact mask ORing 572 MN_MASK_OR, /// mask ORing 573 MN_GET_VARIANT, /// get register variant 574 MN_VARIABLE, /// return variable-like for register 575 }; 576 /// return macro name defined in the macro header 577 virtual std::string macro_name(macro_name_t macro, bool relative = false) const = 0; 578 /// flag to consider 579 enum register_flag_t 580 { 581 RF_GENERATE_ALL_INST, /// for range instance, generate one macro set per instance ? 582 RF_GENERATE_PARAM_INST, /// for range instance, generate a parametrised macro set ? 583 }; 584 /** tweak instance generaton and its children 585 * NOTE: for range flags, although the instance will be numbered, the index is 586 * to be ignored */ 587 virtual bool register_flag(const node_inst_t& inst, register_flag_t flag) const = 0; 588 /// prefix/suffix type 589 enum macro_type_t 590 { 591 MT_NODE_ADDR, /// node address 592 MT_REG_ADDR, /// register address 593 MT_REG_OFFSET, /// register address relative to parent node 594 MT_REG_TYPE, /// register type 595 MT_REG_NAME, /// register prefix for fields 596 MT_REG_INDEX, /// register index/indices 597 MT_REG_VAR, /// variable-like macro 598 MT_FIELD_BP, /// bit position of a field 599 MT_FIELD_BM, /// bit mask of a field 600 MT_FIELD_BV, /// bit value of a field enum 601 MT_FIELD_BF, /// bit field value: (v << pos) & mask 602 MT_FIELD_BFM, /// ignore value and return mask 603 MT_FIELD_BFV, /// bit field enum value: (enum_v << pos) & mask 604 MT_FIELD_BFMV, /// ignore value and return mask 605 MT_IO_TYPE, /// register io type 606 }; 607 /// register access types 608 enum access_type_t 609 { 610 AT_RO, /// read-only: write are disallowed 611 AT_RW, /// read-write: read/writes are allowed, field write by generated a RMW 612 AT_WO, /// write-only: read are disallowed, field write will set other fields to 0 613 }; 614 /// register operation 615 enum register_op_t 616 { 617 RO_VAR, /// variable-like 618 RO_READ, /// read 619 RO_WRITE, /// write 620 RO_RMW, /// read-modify-write 621 }; 622 /// return type prefix/suffix for register macro 623 virtual std::string type_xfix(macro_type_t type, bool prefix) const = 0; 624 /// return variant prefix/suffix 625 virtual std::string variant_xfix(const std::string& variant, bool prefix) const = 0; 626 /// return instance prefix in macro name 627 virtual std::string inst_prefix(const node_inst_t& inst) const = 0; 628 /// return field prefix in field macro names 629 virtual std::string field_prefix() const = 0; 630 /// return field enum prefix in field macro names 631 virtual std::string enum_prefix() const = 0; 632 /// return the field enum name in field macro names 633 virtual std::string enum_name(const enum_ref_t& enum_) const = 0; 634 /// return instance name in macro, default is instance name then index if any 635 virtual std::string instance_name(const node_inst_t& inst, bool parametric) const; 636 /// return field name in macro, default is field name 637 virtual std::string field_name(const field_ref_t& field) const; 638 /// return the complete macro name with prefix, default uses all the other functions 639 virtual std::string macro_basename(const pseudo_node_inst_t& inst) const; 640 /// return the complete macro name with prefix, default uses macro_basename() 641 virtual std::string macro_basename(const pseudo_node_inst_t& inst, macro_type_t type) const; 642 /// generate address string for a register instance, and fill the parametric 643 /// argument list, default does it the obvious way and parameters are _n1, _n2, ... 644 virtual std::string register_address(const pseudo_node_inst_t& reg, 645 std::vector< std::string >& params, bool offset_only = false) const; 646 /// return access type for a variant and a given register access 647 /// NOTE variant with the unspecified access type will be promoted to register access 648 virtual access_type_t register_access(const std::string& variant, access_t access) const = 0; 649 /// return register type name 650 virtual std::string register_type_name(access_type_t access, int width) const; 651 /// get register operation name 652 virtual std::string register_op_name(register_op_t op, bool relative = false) const; 653 /// register operation prefix 654 virtual std::string register_op_prefix() const; 655 /// generate a macro pasting that is safe even when macro is empty 656 /// ie: safe_macro_paste(false, "A") -> ##A 657 /// ie: safe_macro_paste(false, "A") -> 658 std::string safe_macro_paste(bool left, const std::string& macro) const; 659 /// generate SCT macros using register variant ? 660 virtual bool has_sct() const = 0; 661 /// return the associated SCT variant (only if RF_GENERATE_SCT) 662 /// empty means don't generate 663 virtual std::string sct_variant(macro_name_t name) const = 0; 664 665private: 666 void gather_files(const pseudo_node_inst_t& inst, const std::string& prefix, 667 std::map< std::string, std::vector< pseudo_node_inst_t > >& map); 668 void print_inst(const pseudo_node_inst_t& inst, bool end = true); // debug 669 std::vector< soc_ref_t > list_socs(const std::vector< pseudo_node_inst_t >& list); 670 bool generate_register(std::ostream& os, const pseudo_node_inst_t& reg); 671 bool generate_node(std::ostream& os, const pseudo_node_inst_t& node); 672 std::string generate_param_str(const std::vector<std::string>& params); 673 void generate_macro_type_ops(access_type_t at, int width, bool relative, 674 define_align_context_t& ctx); 675 void generate_macro_reg_ops(const std::string& bf_readx, 676 const std::string& bf_or, 677 bool relative, std::ofstream& fout); 678 bool generate_macro_header(error_context_t& ectx); 679}; 680 681std::string common_generator::instance_name(const node_inst_t& inst, bool parametric) const 682{ 683 std::ostringstream oss; 684 oss << inst.name(); 685 if(inst.is_indexed() && !parametric) 686 oss << inst.index(); 687 return oss.str(); 688} 689 690std::string common_generator::field_name(const field_ref_t& field) const 691{ 692 return field.get()->name; 693} 694 695std::string common_generator::macro_basename(const pseudo_node_inst_t& inst_) const 696{ 697 pseudo_node_inst_t inst = inst_; 698 std::string str; 699 while(!inst.inst.is_root()) 700 { 701 str = instance_name(inst.inst, inst.parametric.back()) + str; 702 inst.inst = inst.inst.parent(); 703 inst.parametric.pop_back(); 704 if(!inst.inst.is_root()) 705 str = inst_prefix(inst.inst) + str; 706 } 707 return str; 708} 709 710std::string common_generator::macro_basename(const pseudo_node_inst_t& inst, macro_type_t type) const 711{ 712 return type_xfix(type, true) + macro_basename(inst); 713} 714 715void common_generator::print_inst(const pseudo_node_inst_t& inst, bool end) 716{ 717 if(!inst.inst.is_root()) 718 { 719 pseudo_node_inst_t p = inst; 720 p.inst = p.inst.parent(); 721 p.parametric.pop_back(); 722 print_inst(p, false); 723 printf(".%s", inst.inst.name().c_str()); 724 if(inst.inst.is_indexed()) 725 { 726 if(inst.parametric.back()) 727 printf("[]"); 728 else 729 printf("[%u]", (unsigned)inst.inst.index()); 730 } 731 } 732 else 733 { 734 printf("%s", inst.inst.soc().get()->name.c_str()); 735 } 736 if(end) 737 printf("\n"); 738} 739 740std::string common_generator::register_type_name(access_type_t access, int width) const 741{ 742 std::ostringstream oss; 743 oss << width << "_"; 744 switch(access) 745 { 746 case AT_RO: oss << "RO"; break; 747 case AT_RW: oss << "RW"; break; 748 case AT_WO: oss << "WO"; break; 749 default: oss << "error"; break; 750 } 751 return type_xfix(MT_IO_TYPE, true) + oss.str() + type_xfix(MT_IO_TYPE, false); 752} 753 754std::string common_generator::register_op_name(register_op_t op, bool relative) const 755{ 756 switch(op) 757 { 758 case RO_VAR: return relative ? "VARREL" : "VAR"; 759 case RO_READ: return relative ? "RDREL" : "RD"; 760 case RO_WRITE: return relative ? "WRREL" : "WR"; 761 case RO_RMW: return relative ? "RMWREL" : "RMW"; 762 default: return "<op>"; 763 } 764} 765 766std::string common_generator::register_op_prefix() const 767{ 768 return "_"; 769} 770 771std::string common_generator::safe_macro_paste(bool left, const std::string& macro) const 772{ 773 if(macro.size() == 0) 774 return ""; 775 return left ? "##" + macro : macro + "##"; 776} 777 778void common_generator::gather_files(const pseudo_node_inst_t& inst, const std::string& prefix, 779 std::map< std::string, std::vector< pseudo_node_inst_t > >& map) 780{ 781 if(!inst.inst.is_root()) 782 map[prefix + register_header(inst.inst)].push_back(inst); 783 784 // if asked, generate one for each instance 785 std::vector< node_inst_t > list = inst.inst.children(); 786 for(size_t i = 0; i < list.size(); i++) 787 { 788 pseudo_node_inst_t c = inst; 789 c.inst = list[i]; 790 if(!list[i].is_indexed() || register_flag(inst.inst, RF_GENERATE_ALL_INST)) 791 { 792 c.parametric.push_back(false); 793 gather_files(c, prefix, map); 794 c.parametric.pop_back(); 795 } 796 if(list[i].is_indexed() && register_flag(list[i], RF_GENERATE_PARAM_INST)) 797 { 798 bool first = list[i].index() == list[i].get()->range.first; 799 if(first) 800 { 801 c.parametric.push_back(true); 802 gather_files(c, prefix, map); 803 } 804 } 805 } 806} 807 808std::vector< soc_ref_t > common_generator::list_socs(const std::vector< pseudo_node_inst_t >& list) 809{ 810 std::set< soc_ref_t > socs; 811 std::vector< pseudo_node_inst_t >::const_iterator it = list.begin(); 812 for(; it != list.end(); ++it) 813 socs.insert(it->inst.soc()); 814 std::vector< soc_ref_t > soc_list; 815 for(std::set< soc_ref_t >::iterator jt = socs.begin(); jt != socs.end(); ++jt) 816 soc_list.push_back(*jt); 817 return soc_list; 818} 819 820std::string common_generator::header_include_guard(const std::string& filename) 821{ 822 std::string guard = "__HEADERGEN_" + toupper(filename) + "__"; 823 for(size_t i = 0; i < guard.size(); i++) 824 if(!isalnum(guard[i])) 825 guard[i] = '_'; 826 return guard; 827} 828 829std::string common_generator::register_address(const pseudo_node_inst_t& reg, 830 std::vector< std::string >& params, bool offset_only) const 831{ 832 std::ostringstream oss; 833 unsigned counter = 1; 834 size_t start_index = offset_only ? reg.parametric.size() - 1 : 0; 835 oss << "("; 836 for(size_t i = start_index; i < reg.parametric.size(); i++) 837 { 838 if(i != start_index) 839 oss << " + "; 840 841 node_inst_t ninst = reg.inst.parent(reg.parametric.size() - i - 1); 842 instance_t& inst = *ninst.get(); 843 if(reg.parametric[i]) 844 params.push_back("_n" + to_str(counter++)); 845 if(inst.type == instance_t::RANGE) 846 { 847 if(inst.range.type == range_t::STRIDE) 848 { 849 if(reg.parametric[i]) 850 { 851 oss << to_hex(inst.range.base) << " + "; 852 oss << "(" << params.back() << ") * " << to_hex(inst.range.stride); 853 } 854 else 855 oss << to_hex(inst.range.base + ninst.index() * inst.range.stride); 856 } 857 else if(inst.range.type == range_t::FORMULA) 858 { 859 if(!reg.parametric[i]) 860 { 861 soc_word_t res; 862 std::map< std::string, soc_word_t > vars; 863 vars[inst.range.variable] = ninst.index(); 864 error_context_t ctx; 865 if(!evaluate_formula(inst.range.formula, vars, res, "", ctx)) 866 oss << "#error cannot evaluate formula"; 867 else 868 oss << to_hex(res); 869 } 870 else 871 oss << strsubst(inst.range.formula, inst.range.variable, 872 "(" + params.back() + ")"); 873 } 874 else if(inst.range.type == range_t::LIST) 875 { 876 if(reg.parametric[i]) 877 { 878 oss << "("; 879 for(size_t j = 0; j + 1 < inst.range.list.size(); j++) 880 { 881 oss << "(" << params.back() << ") == " << (inst.range.first + j) 882 << " ? " << to_hex(inst.range.list[j]) << " : "; 883 } 884 oss << to_hex(inst.range.list.back()) << ")"; 885 } 886 else 887 oss << to_hex(inst.range.list[ninst.index() - inst.range.first]); 888 } 889 else 890 { 891 return "#error unknown range type"; 892 } 893 } 894 else if(inst.type == instance_t::SINGLE) 895 oss << to_hex(inst.addr); 896 else if (inst.type == instance_t::FLOATING) 897 return ""; 898 else 899 return "#error unknown instance type"; 900 } 901 oss << ")"; 902 return oss.str(); 903} 904 905bool common_generator::generate_register(std::ostream& os, const pseudo_node_inst_t& reg) 906{ 907 os << "\n"; 908 define_align_context_t ctx; 909 std::vector< std::string > addr_params; 910 std::vector< std::string > offset_params; 911 std::string addr = register_address(reg, addr_params); 912 std::string offset = register_address(reg, offset_params, true); 913 std::string basename = macro_basename(reg); 914 std::string addr_param_str = generate_param_str(addr_params); 915 std::string offset_param_str = generate_param_str(offset_params); 916 std::string bp_prefix = macro_basename(reg, MT_FIELD_BP) + field_prefix(); 917 std::string bm_prefix = macro_basename(reg, MT_FIELD_BM) + field_prefix(); 918 std::string bf_prefix = macro_basename(reg, MT_FIELD_BF) + field_prefix(); 919 std::string bfm_prefix = macro_basename(reg, MT_FIELD_BFM) + field_prefix(); 920 std::string bfv_prefix = macro_basename(reg, MT_FIELD_BFV) + field_prefix(); 921 std::string bfmv_prefix = macro_basename(reg, MT_FIELD_BFMV) + field_prefix(); 922 bool has_addr = !addr.empty(); 923 924 register_ref_t regr = reg.inst.node().reg(); 925 /* handle register the same way as variants */ 926 std::vector< std::string > var_prefix; 927 std::vector< std::string > var_suffix; 928 std::vector< std::string > var_addr; 929 std::vector< std::string > var_offset; 930 std::vector< access_type_t > var_access; 931 932 var_prefix.push_back(""); 933 var_suffix.push_back(""); 934 var_access.push_back(register_access("", regr.get()->access)); 935 if(has_addr) 936 var_addr.push_back(addr); 937 var_offset.push_back(offset); 938 939 std::vector< variant_ref_t > variants = regr.variants(); 940 for(size_t i = 0; i < variants.size(); i++) 941 { 942 var_prefix.push_back(variant_xfix(variants[i].type(), true)); 943 var_suffix.push_back(variant_xfix(variants[i].type(), false)); 944 if (has_addr) 945 { 946 var_addr.push_back("(" + type_xfix(MT_REG_ADDR, true) + basename + 947 type_xfix(MT_REG_ADDR, false) + addr_param_str + " + " + 948 to_hex(variants[i].offset()) + ")"); 949 } 950 var_offset.push_back("(" + type_xfix(MT_REG_OFFSET, true) + basename + 951 type_xfix(MT_REG_OFFSET, false) + offset_param_str + " + " + 952 to_hex(variants[i].offset())); 953 access_t acc = variants[i].get()->access; 954 if(acc == UNSPECIFIED) 955 acc = regr.get()->access; // fallback to register access 956 var_access.push_back(register_access(variants[i].type(), acc)); 957 } 958 959 for(size_t i = 0; i < var_prefix.size(); i++) 960 { 961 std::string var_basename = var_prefix[i] + basename + var_suffix[i]; 962 std::string macro_var = type_xfix(MT_REG_VAR, true) + var_basename + 963 type_xfix(MT_REG_VAR, false); 964 std::string macro_addr = type_xfix(MT_REG_ADDR, true) + var_basename + 965 type_xfix(MT_REG_ADDR, false); 966 std::string macro_offset = type_xfix(MT_REG_OFFSET, true) + var_basename + 967 type_xfix(MT_REG_OFFSET, false); 968 std::string macro_type = type_xfix(MT_REG_TYPE, true) + var_basename + 969 type_xfix(MT_REG_TYPE, false); 970 std::string macro_prefix = type_xfix(MT_REG_NAME, true) + var_basename + 971 type_xfix(MT_REG_NAME, false); 972 std::string macro_index = type_xfix(MT_REG_INDEX, true) + var_basename + 973 type_xfix(MT_REG_INDEX, false); 974 /* print VAR macro: 975 * if we have support macros then we generate something like HW(basename) 976 * where HW is some support macros to support complex operations. Otherwise 977 * we just generate something like (*(volatile unsigned uintN_t)basename_addr) */ 978 if (has_addr) 979 { 980 if(!has_support_macros()) 981 { 982 std::ostringstream oss; 983 oss << "(*(volatile uint" << regr.get()->width << "_t *)" << 984 macro_addr + addr_param_str << ")"; 985 ctx.add(macro_var + addr_param_str, oss.str()); 986 } 987 else 988 { 989 ctx.add(macro_var + addr_param_str, macro_name(MN_VARIABLE) + 990 "(" + var_basename + addr_param_str + ")"); 991 } 992 993 /* print ADDR macro */ 994 ctx.add(macro_addr + addr_param_str, var_addr[i]); 995 } 996 else 997 ctx.add(macro_var + addr_param_str, macro_name(MN_VARIABLE) + "(" + var_basename + addr_param_str + ")"); 998 999 if(has_offsets()) 1000 { 1001 /* print OFFSET macro */ 1002 ctx.add(macro_offset + offset_param_str, var_offset[i]); 1003 } 1004 1005 /* disable macros if needed */ 1006 if(has_support_macros()) 1007 { 1008 /* print TYPE macro */ 1009 ctx.add(macro_type + addr_param_str, register_type_name(var_access[i], regr.get()->width)); 1010 /* print PREFIX macro */ 1011 ctx.add(macro_prefix + addr_param_str, basename); 1012 1013 if(has_sct()) 1014 { 1015 /* print INDEX macro */ 1016 ctx.add(macro_index + addr_param_str, addr_param_str); 1017 } 1018 } 1019 } 1020 /* print fields */ 1021 std::vector< field_ref_t > fields = regr.fields(); 1022 for(size_t i = 0; i < fields.size(); i++) 1023 { 1024 /* print BP macro: pos */ 1025 std::string fname = field_name(fields[i]); 1026 ctx.add(bp_prefix + fname + type_xfix(MT_FIELD_BP, false), 1027 to_str(fields[i].get()->pos)); 1028 /* print BM macro: mask */ 1029 ctx.add(bm_prefix + fname + type_xfix(MT_FIELD_BM, false), 1030 to_hex(fields[i].get()->bitmask())); 1031 std::vector< enum_ref_t > enums = fields[i].enums(); 1032 std::string bv_prefix = macro_basename(reg, MT_FIELD_BV) + field_prefix() 1033 + fname + enum_prefix(); 1034 /* print BV macros: enum_v */ 1035 for(size_t j = 0; j < enums.size(); j++) 1036 ctx.add(bv_prefix + enum_name(enums[j]) + type_xfix(MT_FIELD_BV, false), 1037 to_hex(enums[j].get()->value)); 1038 /* print BF macro: (((v) & mask) << pos) */ 1039 ctx.add(bf_prefix + fname + type_xfix(MT_FIELD_BF, false) + "(v)", 1040 "(((v) & " + to_hex(fields[i].get()->unshifted_bitmask()) + ") << " + 1041 to_str(fields[i].get()->pos) + ")"); 1042 /* print BFM macro: masl */ 1043 ctx.add(bfm_prefix + fname + type_xfix(MT_FIELD_BFM, false) + "(v)", 1044 bm_prefix + fname + type_xfix(MT_FIELD_BM, false)); 1045 /* print BFV macro: ((enum_v) << pos) & mask) */ 1046 ctx.add(bfv_prefix + fname + type_xfix(MT_FIELD_BFV, false) + "(e)", 1047 bf_prefix + fname + type_xfix(MT_FIELD_BF, false) + "(" + 1048 bv_prefix + "##e)"); 1049 /* print BFMV macro: masl */ 1050 ctx.add(bfmv_prefix + fname + type_xfix(MT_FIELD_BFMV, false) + "(v)", 1051 bm_prefix + fname + type_xfix(MT_FIELD_BM, false)); 1052 } 1053 1054 ctx.print(os); 1055 return true; 1056} 1057 1058bool common_generator::generate_node(std::ostream& os, const pseudo_node_inst_t& node) 1059{ 1060 define_align_context_t ctx; 1061 std::vector< std::string > params; 1062 std::string addr = register_address(node, params); 1063 std::string basename = macro_basename(node); 1064 std::string param_str = generate_param_str(params); 1065 std::string macro_addr = type_xfix(MT_NODE_ADDR, true) + basename + 1066 type_xfix(MT_NODE_ADDR, false); 1067 bool has_addr = !addr.empty(); 1068 1069 if (has_addr) 1070 { 1071 os << "\n"; 1072 ctx.add(macro_addr + param_str, addr); 1073 } 1074 1075 ctx.print(os); 1076 return true; 1077} 1078 1079std::string common_generator::generate_param_str(const std::vector<std::string>& params) 1080{ 1081 std::string param_str; 1082 1083 if(params.size() > 0) 1084 { 1085 param_str = "("; 1086 1087 for(size_t i = 0; i < params.size(); i++) 1088 param_str += (i == 0 ? "" : ",") + params[i]; 1089 1090 param_str += ")"; 1091 } 1092 1093 return param_str; 1094} 1095 1096void common_generator::generate_macro_type_ops(access_type_t at, int width, bool relative, 1097 define_align_context_t& ctx) 1098{ 1099 std::string io_type = register_type_name(at, width); 1100 macro_type_t mt = relative ? MT_REG_OFFSET : MT_REG_ADDR; 1101 std::string args = relative ? "name, base" : "name"; 1102 std::string reg_addr = safe_macro_paste(false, type_xfix(mt, true)) 1103 + "name" + safe_macro_paste(true, type_xfix(mt, false)); 1104 1105 if(relative) 1106 reg_addr = "(base) + " + reg_addr; 1107 1108 // read 1109 std::ostringstream oss; 1110 if(at == AT_RO) 1111 oss << "(*(const volatile uint" << width << "_t *)(" << reg_addr << "))"; 1112 else if(at == AT_RW) 1113 oss << "(*(volatile uint" << width << "_t *)(" << reg_addr << "))"; 1114 else 1115 oss << "({_Static_assert(0, #name \" is write-only\"); 0;})"; 1116 ctx.add(io_type + register_op_prefix() + register_op_name(RO_READ, relative) + "(" + args + ", ...)", 1117 oss.str()); 1118 // write 1119 oss.str(""); 1120 if(at != AT_RO) 1121 oss << "(*(volatile uint" << width << "_t *)(" << reg_addr << ")) = (val)"; 1122 else 1123 oss << "_Static_assert(0, #name \" is read-only\")"; 1124 ctx.add(io_type + register_op_prefix() + register_op_name(RO_WRITE, relative) + "(" + args + ", val)", 1125 oss.str()); 1126 // read-modify-write 1127 oss.str(""); 1128 if(at == AT_RW) 1129 { 1130 oss << io_type << register_op_prefix() << register_op_name(RO_WRITE, relative) + "(" + args + ", "; 1131 oss << "(" << io_type << register_op_prefix() << register_op_name(RO_READ, relative) + "(" + args + ") & (vand))"; 1132 oss << " | (vor))"; 1133 } 1134 else if(at == AT_WO) 1135 oss << io_type << register_op_prefix() << register_op_name(RO_WRITE, relative) + "(" + args + ", vor)"; 1136 else 1137 oss << "_Static_assert(0, #name \" is read-only\")"; 1138 ctx.add(io_type + register_op_prefix() + register_op_name(RO_RMW, relative) + "(" + args + ", vand, vor)", 1139 oss.str()); 1140 // variable 1141 oss.str(""); 1142 if(at == AT_RO) 1143 oss << "(*(const volatile uint" << width << "_t *)(" << reg_addr << "))"; 1144 else 1145 oss << "(*(volatile uint" << width << "_t *)(" << reg_addr << "))"; 1146 ctx.add(io_type + register_op_prefix() + register_op_name(RO_VAR, relative) + "(" + args + ", ...)", 1147 oss.str()); 1148} 1149 1150void common_generator::generate_macro_reg_ops(const std::string& bf_readx, 1151 const std::string& bf_or, 1152 bool relative, std::ofstream& fout) 1153{ 1154 std::string args = relative ? "base, name" : "name"; 1155 std::string argswap = relative ? "name, base" : "name"; 1156 std::string argbase = relative ? "base, " : ""; 1157 std::string docline; 1158 1159 if(relative) 1160 docline = " * register address is calculated by offsetting from the base address\n"; 1161 1162 /* print REG_READ macro */ 1163 std::string reg_read = macro_name(MN_REG_READ, relative); 1164 fout << "/** " << reg_read << "\n"; 1165 fout << " *\n"; 1166 fout << " * usage: " << reg_read << "(" << argbase << "register)\n"; 1167 fout << " *\n"; 1168 fout << " * effect: read the register and return its value\n"; 1169 fout << docline; 1170 fout << " * note: register must be fully qualified if indexed\n"; 1171 fout << " *\n"; 1172 fout << " * example: " << reg_read << "(" << argbase << "ICOLL_STATUS)\n"; 1173 fout << " * " << reg_read << "(" << argbase << "ICOLL_ENABLE(42))\n"; 1174 fout << " */\n"; 1175 fout << "#define " << reg_read << "(" << args << ") " 1176 << safe_macro_paste(false, type_xfix(MT_REG_TYPE, true)) << "name" 1177 << safe_macro_paste(true, type_xfix(MT_REG_TYPE, false)) 1178 << "(" << register_op_name(RO_READ, relative) << ", " << argswap << ")\n"; 1179 fout << "\n"; 1180 1181 /* print FIELD_READ macro */ 1182 std::string bf_read = macro_name(MN_FIELD_READ, relative); 1183 fout << "/** " << bf_read << "\n"; 1184 fout << " *\n"; 1185 fout << " * usage: " << bf_read << "(" << argbase << "register, field)\n"; 1186 fout << " *\n"; 1187 fout << " * effect: read a register and return the value of a particular field\n"; 1188 fout << docline; 1189 fout << " * note: register must be fully qualified if indexed\n"; 1190 fout << " *\n"; 1191 fout << " * example: " << bf_read << "(" << argbase << "ICOLL_CTRL, SFTRST)\n"; 1192 fout << " * " << bf_read << "(" << argbase << "ICOLL_ENABLE(3), CPU0_PRIO)\n"; 1193 fout << " */\n"; 1194 fout << "#define " << bf_read << "(" << args << ", field) " << bf_read << "_(" 1195 << reg_read << "(" << args << "), " << safe_macro_paste(false, type_xfix(MT_REG_NAME, true)) 1196 << "name" << safe_macro_paste(true, type_xfix(MT_REG_NAME, false)) << ", field)\n"; 1197 fout << "#define " << bf_read << "_(...) " << bf_readx << "(__VA_ARGS__)\n"; 1198 fout << "\n"; 1199 1200 /* print REG_WRITE macro */ 1201 std::string reg_write = macro_name(MN_REG_WRITE, relative); 1202 fout << "/** " << reg_write << "\n"; 1203 fout << " *\n"; 1204 fout << " * usage: " << reg_write << "(" << argbase << "register, value)\n"; 1205 fout << " *\n"; 1206 fout << " * effect: write a register\n"; 1207 fout << docline; 1208 fout << " * note: register must be fully qualified if indexed\n"; 1209 fout << " *\n"; 1210 fout << " * example: " << reg_write << "(" << argbase << "ICOLL_CTRL, 0x42)\n"; 1211 fout << " * " << reg_write << "(" << argbase << "ICOLL_ENABLE_SET(3), 0x37)\n"; 1212 fout << " */\n"; 1213 fout << "#define " << reg_write << "(" << args << ", val) " 1214 << safe_macro_paste(false, type_xfix(MT_REG_TYPE, true)) << "name" 1215 << safe_macro_paste(true, type_xfix(MT_REG_TYPE, false)) 1216 << "(" << register_op_name(RO_WRITE, relative) << ", " << argswap << ", val)\n"; 1217 fout << "\n"; 1218 1219 /* print FIELD_WRITE macro */ 1220 std::string bf_write = macro_name(MN_FIELD_WRITE, relative); 1221 fout << "/** " << bf_write << "\n"; 1222 fout << " *\n"; 1223 fout << " * usage: " << bf_write << "(" << argbase << "register, f1(v1), f2(v2), ...)\n"; 1224 fout << " *\n"; 1225 fout << " * effect: change the register value so that field fi has value vi\n"; 1226 fout << docline; 1227 fout << " * note: register must be fully qualified if indexed\n"; 1228 fout << " * note: this macro may perform a read-modify-write\n"; 1229 fout << " *\n"; 1230 fout << " * example: " << bf_write << "(" << argbase << "ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))\n"; 1231 fout << " * " << bf_write << "(" << argbase << "ICOLL_ENABLE(3), CPU0_PRIO(1), CPU0_TYPE_V(FIQ))\n"; 1232 fout << " */\n"; 1233 fout << "#define " << bf_write << "(" << args << ", ...) " 1234 << bf_write << "_(" << args << ", " << safe_macro_paste(false, type_xfix(MT_REG_NAME, true)) 1235 << "name" << safe_macro_paste(true, type_xfix(MT_REG_NAME, false)) << ", __VA_ARGS__)\n"; 1236 fout << "#define " << bf_write << "_(" << args << ", name2, ...) " 1237 << safe_macro_paste(false, type_xfix(MT_REG_TYPE, true)) << "name" 1238 << safe_macro_paste(true, type_xfix(MT_REG_TYPE, false)) 1239 << "(" << register_op_name(RO_RMW, relative) << ", " << argswap << ", " 1240 << "~" << macro_name(MN_FIELD_OR_MASK) << "(name2, __VA_ARGS__), " 1241 << macro_name(MN_FIELD_OR) << "(name2, __VA_ARGS__))\n"; 1242 fout << "\n"; 1243 1244 /* print FIELD_OVERWRITE macro */ 1245 std::string bf_overwrite = macro_name(MN_FIELD_OVERWRITE, relative); 1246 fout << "/** " << bf_overwrite << "\n"; 1247 fout << " *\n"; 1248 fout << " * usage: " << bf_overwrite << "(" << argbase << "register, f1(v1), f2(v2), ...)\n"; 1249 fout << " *\n"; 1250 fout << " * effect: change the register value so that field fi has value vi and other fields have value zero\n"; 1251 fout << docline; 1252 fout << " * thus this macro is equivalent to:\n"; 1253 fout << " * " << reg_write << "(" << argbase << "register, " << bf_or << "(register, f1(v1), ...))\n"; 1254 fout << " * note: register must be fully qualified if indexed\n"; 1255 fout << " * note: this macro will overwrite the register (it is NOT a read-modify-write)\n"; 1256 fout << " *\n"; 1257 fout << " * example: " << bf_overwrite << "(ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))\n"; 1258 fout << " * " << bf_overwrite << "(ICOLL_ENABLE(3), CPU0_PRIO(1), CPU0_TYPE_V(FIQ))\n"; 1259 fout << " */\n"; 1260 fout << "#define " << bf_overwrite << "(" << args << ", ...) " 1261 << bf_overwrite << "_(" << args << ", " << safe_macro_paste(false, type_xfix(MT_REG_NAME, true)) 1262 << "name" << safe_macro_paste(true, type_xfix(MT_REG_NAME, false)) << ", __VA_ARGS__)\n"; 1263 fout << "#define " << bf_overwrite << "_(" << args << ", name2, ...) " 1264 << safe_macro_paste(false, type_xfix(MT_REG_TYPE, true)) << "name" 1265 << safe_macro_paste(true, type_xfix(MT_REG_TYPE, false)) 1266 << "(" << register_op_name(RO_WRITE, relative) << ", " << argswap << ", " 1267 << macro_name(MN_FIELD_OR) << "(name2, __VA_ARGS__))\n"; 1268 fout << "\n"; 1269 1270 /* print FIELD_SET/FIELD_CLEAR macro */ 1271 for(int i = 0; i < 2; i++) 1272 { 1273 macro_name_t n = (i == 0) ? MN_FIELD_SET : MN_FIELD_CLEAR; 1274 std::string bf_set = macro_name(n, relative); 1275 std::string set_var = sct_variant(n); 1276 1277 fout << "/** " << bf_set << "\n"; 1278 fout << " *\n"; 1279 fout << " * usage: " << bf_set << "(" << argbase << "register, f1, f2, ...)\n"; 1280 fout << " *\n"; 1281 fout << " * effect: change the register value so that field fi has "; 1282 if(i == 0) 1283 fout << "maximum value\n"; 1284 else 1285 fout << "value zero\n"; 1286 fout << docline; 1287 if(has_sct()) 1288 fout << " * IMPORTANT: this macro performs a write to the " << set_var << " variant of the register\n"; 1289 else 1290 fout << " * note: this macro will perform a read-modify-write\n"; 1291 1292 fout << " * note: register must be fully qualified if indexed\n"; 1293 fout << " *\n"; 1294 fout << " * example: " << bf_set << "(" << argbase << "ICOLL_CTRL, SFTRST, CLKGATE)\n"; 1295 fout << " * " << bf_set << "(" << argbase << "ICOLL_ENABLE(3), CPU0_PRIO, CPU0_TYPE)\n"; 1296 fout << " */\n"; 1297 1298 if(has_sct()) 1299 { 1300 fout << "#define " << bf_set << "(" << args << ", ...) " << bf_set << "_(" << argbase 1301 << macro_name(MN_GET_VARIANT) << "(name, " << variant_xfix(set_var, true) 1302 << ", " << variant_xfix(set_var, false) << "), " 1303 << safe_macro_paste(false, type_xfix(MT_REG_NAME, true)) 1304 << "name" << safe_macro_paste(true, type_xfix(MT_REG_NAME, false)) 1305 << ", __VA_ARGS__)\n"; 1306 fout << "#define " << bf_set << "_(" << args << ", name2, ...) " << macro_name(MN_REG_WRITE, relative) 1307 << "(" << args << ", " << macro_name(MN_MASK_OR) << "(name2, __VA_ARGS__))\n"; 1308 } 1309 else 1310 { 1311 fout << "#define " << bf_set << "(" << args << ", ...) " 1312 << bf_set << "_(" << args << ", " << safe_macro_paste(false, type_xfix(MT_REG_NAME, true)) 1313 << "name" << safe_macro_paste(true, type_xfix(MT_REG_NAME, false)) << ", __VA_ARGS__)\n"; 1314 fout << "#define " << bf_set << "_(" << args << ", name2, ...) " 1315 << safe_macro_paste(false, type_xfix(MT_REG_TYPE, true)) << "name" 1316 << safe_macro_paste(true, type_xfix(MT_REG_TYPE, false)) 1317 << "(" << register_op_name(RO_RMW, relative) << ", " << argswap << ", ~"; 1318 if(i == 0) 1319 fout << "0," << macro_name(MN_MASK_OR) << "(name2, __VA_ARGS__))\n"; 1320 else 1321 fout << macro_name(MN_MASK_OR) << "(name2, __VA_ARGS__), 0)\n"; 1322 } 1323 fout << "\n"; 1324 } 1325 1326 if(has_sct()) 1327 { 1328 std::string set_var = sct_variant(MN_FIELD_SET); 1329 std::string clr_var = sct_variant(MN_FIELD_CLEAR); 1330 1331 /* print REG_SET */ 1332 std::string reg_set = macro_name(MN_REG_SET, relative); 1333 fout << "/** " << reg_set << "\n"; 1334 fout << " *\n"; 1335 fout << " * usage: " << reg_set << "(" << argbase << "register, set_value)\n"; 1336 fout << " *\n"; 1337 fout << " * effect: set some bits using " << set_var << " variant\n"; 1338 fout << docline; 1339 fout << " * note: register must be fully qualified if indexed\n"; 1340 fout << " *\n"; 1341 fout << " * example: " << reg_set << "(" << argbase << "ICOLL_CTRL, 0x42)\n"; 1342 fout << " * " << reg_set << "(" << argbase << "ICOLL_ENABLE(3), 0x37)\n"; 1343 fout << " */\n"; 1344 fout << "#define " << reg_set << "(" << args << ", sval) " 1345 << reg_set << "_(" << argbase << macro_name(MN_GET_VARIANT) << "(name, " 1346 << variant_xfix(set_var, true) << ", " << variant_xfix(set_var, false) 1347 << "), sval)\n"; 1348 fout << "#define " << reg_set << "_(" << args << ", sval) " 1349 << macro_name(MN_REG_WRITE, relative) << "(" << args << ", sval)\n"; 1350 fout << "\n"; 1351 1352 /* print REG_CLR */ 1353 std::string reg_clr = macro_name(MN_REG_CLEAR, relative); 1354 fout << "/** " << reg_clr << "\n"; 1355 fout << " *\n"; 1356 fout << " * usage: " << reg_clr << "(" << argbase << "register, clr_value)\n"; 1357 fout << " *\n"; 1358 fout << " * effect: clear some bits using " << clr_var << " variant\n"; 1359 fout << docline; 1360 fout << " * note: register must be fully qualified if indexed\n"; 1361 fout << " *\n"; 1362 fout << " * example: " << reg_clr << "(" << argbase << "ICOLL_CTRL, 0x42)\n"; 1363 fout << " * " << reg_clr << "(" << argbase << "ICOLL_ENABLE(3), 0x37)\n"; 1364 fout << " */\n"; 1365 fout << "#define " << reg_clr << "(" << args << ", cval) " 1366 << reg_clr << "_(" << argbase << macro_name(MN_GET_VARIANT) << "(name, " 1367 << variant_xfix(clr_var, true) << ", " << variant_xfix(clr_var, false) 1368 << "), cval)\n"; 1369 fout << "#define " << reg_clr << "_(" << args << ", cval) " 1370 << macro_name(MN_REG_WRITE, relative) << "(" << args << ", cval)\n"; 1371 fout << "\n"; 1372 1373 /* print REG_CS */ 1374 std::string reg_cs = macro_name(MN_REG_CLEAR_SET, relative); 1375 fout << "/** " << reg_cs << "\n"; 1376 fout << " *\n"; 1377 fout << " * usage: " << reg_cs << "(" << argbase << "register, clear_value, set_value)\n"; 1378 fout << " *\n"; 1379 fout << " * effect: clear some bits using " << clr_var << " variant and then set some using " << set_var << " variant\n"; 1380 fout << docline; 1381 fout << " * note: register must be fully qualified if indexed\n"; 1382 fout << " *\n"; 1383 fout << " * example: " << reg_cs << "(" << argbase << "ICOLL_CTRL, 0xff, 0x42)\n"; 1384 fout << " * " << reg_cs << "(" << argbase << "ICOLL_ENABLE(3), 0xff, 0x37)\n"; 1385 fout << " */\n"; 1386 fout << "#define " << reg_cs << "(" << args << ", cval, sval) " 1387 << reg_cs << "_(" << argbase << macro_name(MN_GET_VARIANT) << "(name, " 1388 << variant_xfix(clr_var, true) << ", " << variant_xfix(clr_var, false) << "), " 1389 << macro_name(MN_GET_VARIANT) << "(name, " << variant_xfix(set_var, true) 1390 << ", " << variant_xfix(set_var, false) << "), cval, sval)\n"; 1391 fout << "#define " << reg_cs << "_(" << argbase << "cname, sname, cval, sval) " 1392 << "do { " << macro_name(MN_REG_WRITE) << "(" << argbase << "cname, cval); " 1393 << macro_name(MN_REG_WRITE, relative) << "(" << argbase << "sname, sval); } while(0)\n"; 1394 fout << "\n"; 1395 1396 /* print BF_CS */ 1397 std::string bf_cs = macro_name(MN_FIELD_CLEAR_SET, relative); 1398 fout << "/** " << bf_cs << "\n"; 1399 fout << " *\n"; 1400 fout << " * usage: " << bf_cs << "(" << argbase << "register, f1(v1), f2(v2), ...)\n"; 1401 fout << " *\n"; 1402 fout << " * effect: change the register value so that field fi has value vi using " << clr_var << " and " << set_var << " variants\n"; 1403 fout << docline; 1404 fout << " * note: register must be fully qualified if indexed\n"; 1405 fout << " * note: this macro will NOT perform a read-modify-write and is thus safer\n"; 1406 fout << " * IMPORTANT: this macro will set some fields to 0 temporarily, make sure this is acceptable\n"; 1407 fout << " *\n"; 1408 fout << " * example: " << bf_cs << "(" << argbase << "ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))\n"; 1409 fout << " * " << bf_cs << "(" << argbase << "ICOLL_ENABLE(3), CPU0_PRIO(1), CPU0_TYPE_V(FIQ))\n"; 1410 fout << " */\n"; 1411 fout << "#define " << bf_cs << "(" << args << ", ...) " 1412 << bf_cs << "_(" << args << ", " << safe_macro_paste(false, type_xfix(MT_REG_NAME, true)) 1413 << "name" << safe_macro_paste(true, type_xfix(MT_REG_NAME, false)) << ", __VA_ARGS__)\n"; 1414 fout << "#define " << bf_cs << "_(" << args << ", name2, ...) " 1415 << macro_name(MN_REG_CLEAR_SET, relative) << "(" << args << ", " << macro_name(MN_FIELD_OR_MASK) 1416 << "(name2, __VA_ARGS__), " << macro_name(MN_FIELD_OR) << "(name2, __VA_ARGS__))\n"; 1417 fout << "\n"; 1418 } 1419 1420 /* print REG_VAR macro */ 1421 std::string reg_var = macro_name(MN_VARIABLE, relative); 1422 fout << "/** " << reg_var << "\n"; 1423 fout << " *\n"; 1424 fout << " * usage: " << reg_var << "(" << argbase << "register)\n"; 1425 fout << " *\n"; 1426 fout << " * effect: return a variable-like expression that can be read/written\n"; 1427 fout << docline; 1428 fout << " * note: register must be fully qualified if indexed\n"; 1429 fout << " * note: read-only registers will yield a constant expression\n"; 1430 fout << " *\n"; 1431 fout << " * example: unsigned x = " << reg_var << "(" << argbase << "ICOLL_STATUS)\n"; 1432 fout << " * unsigned x = " << reg_var << "(" << argbase << "ICOLL_ENABLE(42))\n"; 1433 fout << " * " << reg_var << "(" << argbase << "ICOLL_ENABLE(42)) = 64\n"; 1434 fout << " */\n"; 1435 fout << "#define " << reg_var << "(" << args << ") " 1436 << safe_macro_paste(false, type_xfix(MT_REG_TYPE, true)) << "name" 1437 << safe_macro_paste(true, type_xfix(MT_REG_TYPE, false)) 1438 << "(" << register_op_name(RO_VAR, relative) << ", " << args << ")\n"; 1439 fout << "\n"; 1440} 1441 1442bool common_generator::generate_macro_header(error_context_t& ectx) 1443{ 1444 /* only generate if we need support macros */ 1445 if(!has_support_macros()) 1446 return true; 1447 std::ofstream fout((m_outdir + "/" + macro_header()).c_str()); 1448 if(!fout) 1449 { 1450 printf("Cannot create '%s'\n", (m_outdir + "/" + macro_header()).c_str()); 1451 return false; 1452 } 1453 print_copyright(fout, std::vector< soc_ref_t >()); 1454 std::string guard = header_include_guard(macro_header()); 1455 print_guard(fout, guard, true); 1456 fout << "\n"; 1457 1458 /* ensure that types uintXX_t are defined */ 1459 fout << "#include <stdint.h>\n\n"; 1460 1461 /* print variadic OR macros: 1462 * __VAR_OR1(prefix, suffix) expands to prefix##suffix 1463 * and more n>=2, using multiple layers of macros: 1464 * __VAR_ORn(pre, s01, s02, ..., sn) expands to pre##s01 | .. | pre##sn */ 1465 std::string var_or = "__VAR_OR"; 1466 const int MAX_N = 20; 1467 1468 fout << "#define " << var_or << "1(prefix, suffix) \\\n"; 1469 fout << " (prefix##suffix)\n"; 1470 for(int n = 2; n <= MAX_N; n++) 1471 { 1472 fout << "#define " << var_or << n << "(pre"; 1473 for(int j = 1; j <= n; j++) 1474 fout << ", s" << j; 1475 fout << ") \\\n"; 1476 /* dichotmoty: expands ORn using ORj and ORk where j=n/2 and k=n-j */ 1477 int half = n / 2; 1478 fout << " (" << var_or << half << "(pre"; 1479 for(int j = 1; j <= half; j++) 1480 fout << ", s" << j; 1481 fout << ") | " << var_or << (n - half) << "(pre"; 1482 for(int j = half + 1; j <= n; j++) 1483 fout << ", s" << j; 1484 fout << "))\n"; 1485 } 1486 fout << "\n"; 1487 1488 /* print macro to compute number of arguments */ 1489 std::string var_nargs = "__VAR_NARGS"; 1490 1491 fout << "#define " << var_nargs << "(...) " << var_nargs << "_(__VA_ARGS__"; 1492 for(int i = MAX_N; i >= 1; i--) 1493 fout << ", " << i; 1494 fout << ")\n"; 1495 fout << "#define " << var_nargs << "_("; 1496 for(int i = 1; i <= MAX_N; i++) 1497 fout << "_" << i << ", "; 1498 fout << "N, ...) N\n\n"; 1499 1500 /* print macro for variadic register macros */ 1501 std::string var_expand = "__VAR_EXPAND"; 1502 1503 fout << "#define " << var_expand << "(macro, prefix, ...) " 1504 << var_expand << "_(macro, " << var_nargs << "(__VA_ARGS__), prefix, __VA_ARGS__)\n"; 1505 fout << "#define " << var_expand << "_(macro, cnt, prefix, ...) " 1506 << var_expand << "__(macro, cnt, prefix, __VA_ARGS__)\n"; 1507 fout << "#define " << var_expand << "__(macro, cnt, prefix, ...) " 1508 << var_expand << "___(macro##cnt, prefix, __VA_ARGS__)\n"; 1509 fout << "#define " << var_expand << "___(macro, prefix, ...) " 1510 << "macro(prefix, __VA_ARGS__)\n\n"; 1511 1512 /* print type macros */ 1513 define_align_context_t ctx; 1514 access_type_t at[3] = { AT_RO, AT_RW, AT_WO }; 1515 int width[3] = { 8, 16, 32 }; 1516 for(int i = 0; i < 3; i++) 1517 { 1518 for(int j = 0; j < 3; j++) 1519 { 1520 std::string io_type = register_type_name(at[i], width[j]); 1521 ctx.add(io_type + "(op, name, ...)", io_type + register_op_prefix() + "##op(name, __VA_ARGS__)"); 1522 1523 generate_macro_type_ops(at[i], width[j], false, ctx); 1524 1525 if(has_offsets()) 1526 generate_macro_type_ops(at[i], width[j], true, ctx); 1527 1528 ctx.add_raw("\n"); 1529 } 1530 } 1531 ctx.print(fout); 1532 fout << "\n"; 1533 1534 if(has_sct()) 1535 { 1536 /* print GET_VARIANT macro */ 1537 std::string get_var = macro_name(MN_GET_VARIANT); 1538 fout << "/** " << get_var << "\n"; 1539 fout << " *\n"; 1540 fout << " * usage: " << get_var << "(register, variant_prefix, variant_postfix)\n"; 1541 fout << " *\n"; 1542 fout << " * effect: expands to register variant given as argument\n"; 1543 fout << " * note: internal usage\n"; 1544 fout << " * note: register must be fully qualified if indexed\n"; 1545 fout << " *\n"; 1546 fout << " * example: " << get_var << "(ICOLL_CTRL, , _SET)\n"; 1547 fout << " * example: " << get_var << "(ICOLL_ENABLE(3), , _CLR)\n"; 1548 fout << " */\n"; 1549 fout << "#define " << get_var << "(name, varp, vars) " 1550 << get_var << "_(" << safe_macro_paste(false, type_xfix(MT_REG_NAME, true)) 1551 << "name" << safe_macro_paste(true, type_xfix(MT_REG_NAME, false)) << ", " 1552 << safe_macro_paste(false, type_xfix(MT_REG_INDEX, true)) 1553 << "name" << safe_macro_paste(true, type_xfix(MT_REG_INDEX, false)) << ", varp, vars)\n"; 1554 fout << "#define " << get_var << "_(...) " << get_var << "__(__VA_ARGS__)\n"; 1555 fout << "#define " << get_var << "__(name, index, varp, vars) " 1556 << "varp##name##vars index\n"; 1557 fout << "\n"; 1558 } 1559 1560 /* print BF_OR macro */ 1561 std::string bf_or = macro_name(MN_FIELD_OR); 1562 fout << "/** " << bf_or << "\n"; 1563 fout << " *\n"; 1564 fout << " * usage: " << bf_or << "(register, f1(v1), f2(v2), ...)\n"; 1565 fout << " *\n"; 1566 fout << " * effect: expands to the register value where each field fi has value vi.\n"; 1567 fout << " * Informally: reg_f1(v1) | reg_f2(v2) | ...\n"; 1568 fout << " * note: enumerated values for fields can be obtained by using the syntax:\n"; 1569 fout << " * f1" << type_xfix(MT_FIELD_BFV, false) << "(name)\n"; 1570 fout << " *\n"; 1571 fout << " * example: " << bf_or << "(ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))\n"; 1572 fout << " */\n"; 1573 fout << "#define " << bf_or << "(reg, ...) " 1574 << var_expand << "(" << var_or << ", " << type_xfix(MT_FIELD_BF, true) 1575 << "##reg##" << field_prefix() << ", __VA_ARGS__)\n"; 1576 fout << "\n"; 1577 1578 /* print BF_OR macro */ 1579 std::string bfm_or = macro_name(MN_FIELD_OR_MASK); 1580 fout << "/** " << bfm_or << "\n"; 1581 fout << " *\n"; 1582 fout << " * usage: " << bfm_or << "(register, f1(v1), f2(v2), ...)\n"; 1583 fout << " *\n"; 1584 fout << " * effect: expands to the register value where each field fi has maximum value (vi is ignored).\n"; 1585 fout << " * note: internal usage\n"; 1586 fout << " *\n"; 1587 fout << " * example: " << bfm_or << "(ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))\n"; 1588 fout << " */\n"; 1589 fout << "#define " << bfm_or << "(reg, ...) " 1590 << var_expand << "(" << var_or << ", " << type_xfix(MT_FIELD_BFM, true) 1591 << "##reg##" << field_prefix() << ", __VA_ARGS__)\n"; 1592 fout << "\n"; 1593 1594 /* print BM_OR macro */ 1595 std::string bm_or = macro_name(MN_MASK_OR); 1596 fout << "/** " << bm_or << "\n"; 1597 fout << " *\n"; 1598 fout << " * usage: " << bm_or << "(register, f1, f2, ...)\n"; 1599 fout << " *\n"; 1600 fout << " * effect: expands to the register value where each field fi is set to its maximum value.\n"; 1601 fout << " * Informally: reg_f1_mask | reg_f2_mask | ...\n"; 1602 fout << " *\n"; 1603 fout << " * example: " << bm_or << "(ICOLL_CTRL, SFTRST, CLKGATE)\n"; 1604 fout << " */\n"; 1605 fout << "#define " << bm_or << "(reg, ...) " 1606 << var_expand << "(" << var_or << ", " << type_xfix(MT_FIELD_BM, true) 1607 << "##reg##" << field_prefix() << ", __VA_ARGS__)\n\n"; 1608 fout << "\n"; 1609 1610 /* print FIELD_READX macro */ 1611 std::string bf_readx = macro_name(MN_FIELD_READX); 1612 fout << "/** " << bf_readx << "\n"; 1613 fout << " *\n"; 1614 fout << " * usage: " << bf_readx << "(value, register, field)\n"; 1615 fout << " *\n"; 1616 fout << " * effect: given a register value, return the value of a particular field\n"; 1617 fout << " * note: this macro does NOT read any register\n"; 1618 fout << " *\n"; 1619 fout << " * example: " << bf_readx << "(0xc0000000, ICOLL_CTRL, SFTRST)\n"; 1620 fout << " * " << bf_readx << "(0x46ff, ICOLL_ENABLE, CPU0_PRIO)\n"; 1621 fout << " */\n"; 1622 fout << "#define " << bf_readx << "(val, name, field) " 1623 << "(((val) & " << safe_macro_paste(false, type_xfix(MT_FIELD_BM, true)) 1624 << "name" << safe_macro_paste(true, type_xfix(MT_FIELD_BM, false)) 1625 << safe_macro_paste(true, field_prefix()) << "##field" 1626 << ") >> " << safe_macro_paste(false, type_xfix(MT_FIELD_BP, true)) 1627 << "name" << safe_macro_paste(true, type_xfix(MT_FIELD_BP, false)) 1628 << safe_macro_paste(true, field_prefix()) << "##field" 1629 << ")\n"; 1630 fout << "\n"; 1631 1632 /* print FIELD_WRITEX macro */ 1633 std::string bf_writex = macro_name(MN_FIELD_WRITEX); 1634 fout << "/** " << bf_writex << "\n"; 1635 fout << " *\n"; 1636 fout << " * usage: " << bf_writex << "(var, register, f1(v1), f2(v2), ...)\n"; 1637 fout << " *\n"; 1638 fout << " * effect: change the variable value so that field fi has value vi\n"; 1639 fout << " * note: this macro will perform a read-modify-write\n"; 1640 fout << " *\n"; 1641 fout << " * example: " << bf_writex << "(var, ICOLL_CTRL, SFTRST(1), CLKGATE(0), TZ_LOCK_V(UNLOCKED))\n"; 1642 fout << " * " << bf_writex << "(var, ICOLL_ENABLE, CPU0_PRIO(1), CPU0_TYPE_V(FIQ))\n"; 1643 fout << " */\n"; 1644 fout << "#define " << bf_writex << "(var, name, ...) " 1645 << "(var) = " << macro_name(MN_FIELD_OR) << "(name, __VA_ARGS__) | (~" 1646 << macro_name(MN_FIELD_OR_MASK) << "(name, __VA_ARGS__) & (var))\n"; 1647 fout << "\n"; 1648 1649 generate_macro_reg_ops(bf_readx, bf_or, false, fout); 1650 1651 if(has_offsets()) 1652 generate_macro_reg_ops(bf_readx, bf_or, true, fout); 1653 1654 print_guard(fout, guard, false); 1655 fout.close(); 1656 return true; 1657} 1658 1659bool common_generator::generate(error_context_t& ectx) 1660{ 1661 /* first find which inst goes to which file */ 1662 std::map< std::string, std::vector< pseudo_node_inst_t > > regmap; 1663 for(size_t i = 0; i < m_soc.size(); i++) 1664 { 1665 soc_ref_t soc(&m_soc[i]); 1666 pseudo_node_inst_t inst; 1667 inst.inst = soc.root_inst(); 1668 gather_files(inst, has_selectors() ? selector_soc_dir(soc) + "/" : 1669 "", regmap); 1670 } 1671 /* create output directory */ 1672 create_dir(m_outdir); 1673 /* print files */ 1674 std::map< std::string, std::vector< pseudo_node_inst_t > >::iterator it = regmap.begin(); 1675 for(; it != regmap.end(); ++it) 1676 { 1677 create_alldir(m_outdir, it->first.c_str()); 1678 std::ofstream fout((m_outdir + "/" + it->first).c_str()); 1679 if(!fout) 1680 { 1681 printf("Cannot create '%s'\n", (m_outdir + "/" + it->first).c_str()); 1682 return false; 1683 } 1684 std::vector< soc_ref_t > soc_list = list_socs(it->second); 1685 print_copyright(fout, soc_list); 1686 std::string guard = header_include_guard(it->first); 1687 print_guard(fout, guard, true); 1688 1689 /* if we generate selectors, we include the macro header in them, otherwise 1690 * we include the macro header right here. If we don't need support macros, 1691 * we also don't include it. */ 1692 if(!has_selectors() && has_support_macros()) 1693 { 1694 fout << "\n"; 1695 fout << "#include \"" << macro_header() << "\"\n"; 1696 } 1697 1698 for(size_t i = 0; i < it->second.size(); i++) 1699 { 1700 if(it->second[i].inst.node().reg().valid()) 1701 { 1702 if(!generate_register(fout, it->second[i])) 1703 { 1704 printf("Cannot generate register "); 1705 print_inst(it->second[i]); 1706 return false; 1707 } 1708 } 1709 else if(has_offsets() && !it->second[i].inst.node().is_root()) 1710 { 1711 if(!generate_node(fout, it->second[i])) 1712 { 1713 printf("Cannot generate node "); 1714 print_inst(it->second[i]); 1715 return false; 1716 } 1717 } 1718 } 1719 1720 print_guard(fout, guard, false); 1721 fout.close(); 1722 } 1723 /* for selectors only */ 1724 if(has_selectors()) 1725 { 1726 /* list all possible headers and per soc headers */ 1727 std::map< std::string, std::set< soc_ref_t > > headers; 1728 for(it = regmap.begin(); it != regmap.end(); ++it) 1729 { 1730 /* pick the first instance in the file to extract the file name */ 1731 node_inst_t inst = it->second[0].inst; 1732 headers[register_header(inst)].insert(inst.node().soc()); 1733 } 1734 /* create selector headers */ 1735 std::map< std::string, std::set< soc_ref_t > >::iterator jt; 1736 for(jt = headers.begin(); jt != headers.end(); ++jt) 1737 { 1738 std::ofstream fout((m_outdir + "/" + jt->first).c_str()); 1739 if(!fout) 1740 { 1741 printf("Cannot create selector '%s'\n", (m_outdir + "/" + jt->first).c_str()); 1742 return false; 1743 } 1744 print_copyright(fout, std::vector< soc_ref_t >()); 1745 std::string guard = header_include_guard(jt->first); 1746 print_guard(fout, guard, true); 1747 1748 /* if we generate selectors, we include the macro header in them */ 1749 fout << "\n"; 1750 fout << "#include \"" << macro_header() << "\"\n"; 1751 1752 std::set< soc_ref_t >::iterator kt; 1753 define_align_context_t ctx; 1754 for(kt = jt->second.begin(); kt != jt->second.end(); ++kt) 1755 { 1756 std::ostringstream oss; 1757 oss << "\"" << selector_soc_dir(*kt) << "/" << jt->first << "\""; 1758 ctx.add(selector_soc_macro(*kt), oss.str()); 1759 } 1760 fout << "\n"; 1761 ctx.print(fout); 1762 fout << "\n"; 1763 fout << "#include \"" << selector_include_header() << "\"\n"; 1764 fout << "\n"; 1765 for(kt = jt->second.begin(); kt != jt->second.end(); ++kt) 1766 fout << "#undef " << selector_soc_macro(*kt) << "\n"; 1767 1768 print_guard(fout, guard, false); 1769 fout.close(); 1770 } 1771 } 1772 /* generate macro header */ 1773 if(!generate_macro_header(ectx)) 1774 return false; 1775 return true; 1776} 1777 1778/** 1779 * Generator: jz 1780 */ 1781 1782class jz_generator : public common_generator 1783{ 1784 bool has_support_macros() const 1785 { 1786 return true; 1787 } 1788 1789 bool has_selectors() const 1790 { 1791 return m_soc.size() >= 2; 1792 } 1793 1794 bool has_offsets() const 1795 { 1796 return false; 1797 } 1798 1799 std::string selector_soc_dir(const soc_ref_t& ref) const 1800 { 1801 return ref.get()->name; 1802 } 1803 1804 std::string selector_include_header() const 1805 { 1806 return "select.h"; 1807 } 1808 1809 std::string selector_soc_macro(const soc_ref_t& ref) const 1810 { 1811 return toupper(ref.get()->name) + "_INCLUDE"; 1812 } 1813 1814 std::string register_header(const node_inst_t& inst) const 1815 { 1816 /* one register header per top-level block */ 1817 if(inst.is_root()) 1818 return "<error>"; 1819 if(inst.parent().is_root()) 1820 return tolower(inst.node().name()) + ".h"; 1821 else 1822 return register_header(inst.parent()); 1823 } 1824 1825 std::string macro_name(macro_name_t macro, bool relative) const 1826 { 1827 switch(macro) 1828 { 1829 case MN_REG_READ: return "jz_read"; 1830 case MN_FIELD_READ: return "jz_readf"; 1831 case MN_FIELD_READX: return "jz_vreadf"; 1832 case MN_REG_WRITE: return "jz_write"; 1833 case MN_REG_SET: return "jz_set"; 1834 case MN_REG_CLEAR: return "jz_clr"; 1835 case MN_FIELD_WRITE: return "jz_writef"; 1836 case MN_FIELD_OVERWRITE: return "jz_overwritef"; 1837 case MN_FIELD_WRITEX: return "jz_vwritef"; 1838 case MN_FIELD_SET: return "jz_setf"; 1839 case MN_FIELD_CLEAR: return "jz_clrf"; 1840 case MN_FIELD_TOG: return "jz_togf"; 1841 case MN_FIELD_CLEAR_SET: return "jz_csf"; 1842 case MN_FIELD_OR: return "jz_orf"; 1843 case MN_FIELD_OR_MASK: return "__jz_orfm"; // internal macro 1844 case MN_MASK_OR: return "jz_orm"; 1845 case MN_REG_CLEAR_SET: return "jz_cs"; 1846 case MN_GET_VARIANT: return "__jz_variant"; // internal macro 1847 case MN_VARIABLE: return "jz_reg"; 1848 default: return "<macro_name>"; 1849 } 1850 } 1851 1852 std::string macro_header() const 1853 { 1854 return "macro.h"; 1855 } 1856 1857 bool register_flag(const node_inst_t& inst, register_flag_t flag) const 1858 { 1859 /* make everything parametrized */ 1860 switch(flag) 1861 { 1862 case RF_GENERATE_ALL_INST: return false; 1863 case RF_GENERATE_PARAM_INST: return true; 1864 default: return false; 1865 } 1866 } 1867 1868 std::string type_xfix(macro_type_t type, bool prefix) const 1869 { 1870 switch(type) 1871 { 1872 case MT_REG_ADDR: return prefix ? "JA_" : ""; 1873 case MT_REG_TYPE: return prefix ? "JT_" : ""; 1874 case MT_REG_NAME: return prefix ? "JN_" : ""; 1875 case MT_REG_INDEX: return prefix ? "JI_" : ""; 1876 case MT_REG_VAR: return prefix ? "REG_" : ""; 1877 case MT_FIELD_BP: return prefix ? "BP_" : ""; 1878 case MT_FIELD_BM: return prefix ? "BM_" : ""; 1879 case MT_FIELD_BV: return prefix ? "BV_" : ""; 1880 case MT_FIELD_BF: return prefix ? "BF_" : ""; 1881 case MT_FIELD_BFM: return prefix ? "BFM_" : ""; 1882 case MT_FIELD_BFV: return prefix ? "BF_" : "_V"; 1883 case MT_FIELD_BFMV: return prefix ? "BFM_" : "_V"; 1884 case MT_IO_TYPE: return prefix ? "JIO_" : ""; 1885 default: return "<xfix>"; 1886 } 1887 } 1888 1889 std::string variant_xfix(const std::string& variant, bool prefix) const 1890 { 1891 /* variant X -> reg_X */ 1892 if(prefix) 1893 return ""; 1894 else 1895 return "_" + toupper(variant); 1896 } 1897 1898 std::string inst_prefix(const node_inst_t& inst) const 1899 { 1900 /* separate blocks with _: block_reg */ 1901 return "_"; 1902 } 1903 1904 std::string field_prefix() const 1905 { 1906 /* separate fields with _: block_reg_field */ 1907 return "_"; 1908 } 1909 1910 std::string enum_prefix() const 1911 { 1912 /* separate enums with __: block_reg_field__enum */ 1913 return "__"; 1914 } 1915 1916 std::string enum_name(const enum_ref_t& enum_) const 1917 { 1918 return enum_.get()->name; 1919 } 1920 1921 access_type_t register_access(const std::string& variant, access_t access) const 1922 { 1923 /* SET and CLR are special and always promoted to WO */ 1924 if(variant == "set" || variant == "clr" || access == WRITE_ONLY) 1925 return AT_WO; 1926 else if(access == READ_ONLY) 1927 return AT_RO; 1928 else 1929 return AT_RW; 1930 } 1931 1932 bool has_sct() const 1933 { 1934 return true; 1935 } 1936 1937 std::string sct_variant(macro_name_t name) const 1938 { 1939 switch(name) 1940 { 1941 case MN_FIELD_SET: return "set"; // always use set variant 1942 case MN_FIELD_CLEAR: return "clr"; // always use clr variant 1943 default: return ""; 1944 } 1945 } 1946}; 1947 1948/** 1949 * Generator: imx 1950 */ 1951 1952class imx_generator : public common_generator 1953{ 1954 bool has_support_macros() const 1955 { 1956 return true; 1957 } 1958 1959 bool has_selectors() const 1960 { 1961 return m_soc.size() >= 2; 1962 } 1963 1964 bool has_offsets() const 1965 { 1966 return false; 1967 } 1968 1969 std::string selector_soc_dir(const soc_ref_t& ref) const 1970 { 1971 return ref.get()->name; 1972 } 1973 1974 std::string selector_include_header() const 1975 { 1976 return "select.h"; 1977 } 1978 1979 std::string selector_soc_macro(const soc_ref_t& ref) const 1980 { 1981 return toupper(ref.get()->name) + "_INCLUDE"; 1982 } 1983 1984 std::string register_header(const node_inst_t& inst) const 1985 { 1986 /* one register header per top-level block */ 1987 if(inst.is_root()) 1988 return "<error>"; 1989 if(inst.parent().is_root()) 1990 return tolower(inst.node().name()) + ".h"; 1991 else 1992 return register_header(inst.parent()); 1993 } 1994 1995 std::string macro_name(macro_name_t macro, bool relative) const 1996 { 1997 switch(macro) 1998 { 1999 case MN_REG_READ: return "REG_RD"; 2000 case MN_FIELD_READ: return "BF_RD"; 2001 case MN_FIELD_READX: return "BF_RDX"; 2002 case MN_REG_WRITE: return "REG_WR"; 2003 case MN_REG_SET: return ""; // no macro for this 2004 case MN_REG_CLEAR: return ""; // no macro for this 2005 case MN_FIELD_WRITE: return "BF_WR"; 2006 case MN_FIELD_OVERWRITE: return "BF_WR_ALL"; 2007 case MN_FIELD_WRITEX: return "BF_WRX"; 2008 case MN_FIELD_SET: return "BF_SET"; 2009 case MN_FIELD_CLEAR: return "BF_CLR"; 2010 case MN_FIELD_TOG: return "BF_TOG"; 2011 case MN_FIELD_CLEAR_SET: return "BF_CS"; 2012 case MN_FIELD_OR: return "BF_OR"; 2013 case MN_FIELD_OR_MASK: return "__BFM_OR"; 2014 case MN_MASK_OR: return "BM_OR"; 2015 case MN_REG_CLEAR_SET: return "REG_CS"; 2016 case MN_GET_VARIANT: return "__REG_VARIANT"; 2017 case MN_VARIABLE: return "HW"; 2018 default: return "<macro_name>"; 2019 } 2020 } 2021 2022 std::string macro_header() const 2023 { 2024 return "macro.h"; 2025 } 2026 2027 bool register_flag(const node_inst_t& inst, register_flag_t flag) const 2028 { 2029 /* make everything parametrized */ 2030 switch(flag) 2031 { 2032 case RF_GENERATE_ALL_INST: return false; 2033 case RF_GENERATE_PARAM_INST: return true; 2034 default: return false; 2035 } 2036 } 2037 2038 std::string type_xfix(macro_type_t type, bool prefix) const 2039 { 2040 switch(type) 2041 { 2042 case MT_REG_ADDR: return prefix ? "HWA_" : ""; 2043 case MT_REG_TYPE: return prefix ? "HWT_" : ""; 2044 case MT_REG_NAME: return prefix ? "HWN_" : ""; 2045 case MT_REG_INDEX: return prefix ? "HWI_" : ""; 2046 case MT_REG_VAR: return prefix ? "HW_" : ""; 2047 case MT_FIELD_BP: return prefix ? "BP_" : ""; 2048 case MT_FIELD_BM: return prefix ? "BM_" : ""; 2049 case MT_FIELD_BV: return prefix ? "BV_" : ""; 2050 case MT_FIELD_BF: return prefix ? "BF_" : ""; 2051 case MT_FIELD_BFM: return prefix ? "BFM_" : ""; 2052 case MT_FIELD_BFV: return prefix ? "BF_" : "_V"; 2053 case MT_FIELD_BFMV: return prefix ? "BFM_" : "_V"; 2054 case MT_IO_TYPE: return prefix ? "HWIO_" : ""; 2055 default: return "<xfix>"; 2056 } 2057 } 2058 2059 std::string variant_xfix(const std::string& variant, bool prefix) const 2060 { 2061 /* variant X -> reg_X */ 2062 if(prefix) 2063 return ""; 2064 else 2065 return "_" + toupper(variant); 2066 } 2067 2068 std::string inst_prefix(const node_inst_t& inst) const 2069 { 2070 /* separate blocks with _: block_reg */ 2071 return "_"; 2072 } 2073 2074 std::string field_prefix() const 2075 { 2076 /* separate fields with _: block_reg_field */ 2077 return "_"; 2078 } 2079 2080 std::string enum_prefix() const 2081 { 2082 /* separate enums with __: block_reg_field__enum */ 2083 return "__"; 2084 } 2085 2086 std::string enum_name(const enum_ref_t& enum_) const 2087 { 2088 return enum_.get()->name; 2089 } 2090 2091 access_type_t register_access(const std::string& variant, access_t access) const 2092 { 2093 /* SET, CLR and TOG are special and always promoted to WO */ 2094 if(variant == "set" || variant == "clr" || variant == "tog" || access == WRITE_ONLY) 2095 return AT_WO; 2096 else if(access == READ_ONLY) 2097 return AT_RO; 2098 else 2099 return AT_RW; 2100 } 2101 2102 bool has_sct() const 2103 { 2104 return true; 2105 } 2106 2107 std::string sct_variant(macro_name_t name) const 2108 { 2109 switch(name) 2110 { 2111 case MN_FIELD_SET: return "set"; // always use set variant 2112 case MN_FIELD_CLEAR: return "clr"; // always use clr variant 2113 case MN_FIELD_TOG: return "tog"; // always use tog variant 2114 default: return ""; 2115 } 2116 } 2117}; 2118 2119/** 2120 * Generator: atj 2121 */ 2122 2123class atj_generator : public common_generator 2124{ 2125 bool has_support_macros() const 2126 { 2127 // no support macros 2128 return false; 2129 } 2130 2131 bool has_selectors() const 2132 { 2133 return false; 2134 } 2135 2136 bool has_offsets() const 2137 { 2138 return false; 2139 } 2140 2141 std::string selector_soc_dir(const soc_ref_t& ref) const 2142 { 2143 return ref.get()->name; 2144 } 2145 2146 std::string selector_include_header() const 2147 { 2148 // unused 2149 return "<error>"; 2150 } 2151 2152 std::string selector_soc_macro(const soc_ref_t& ref) const 2153 { 2154 // unused 2155 return "<error>"; 2156 } 2157 2158 std::string register_header(const node_inst_t& inst) const 2159 { 2160 /* one register header per top-level block */ 2161 if(inst.is_root()) 2162 return "<error>"; 2163 if(inst.parent().is_root()) 2164 return tolower(inst.node().name()) + ".h"; 2165 else 2166 return register_header(inst.parent()); 2167 } 2168 2169 std::string macro_name(macro_name_t macro, bool relative) const 2170 { 2171 // no macros are generated 2172 return "<macro_name>"; 2173 } 2174 2175 std::string macro_header() const 2176 { 2177 // unused 2178 return "<error>"; 2179 } 2180 2181 bool register_flag(const node_inst_t& inst, register_flag_t flag) const 2182 { 2183 /* make everything parametrized */ 2184 switch(flag) 2185 { 2186 case RF_GENERATE_ALL_INST: return false; 2187 case RF_GENERATE_PARAM_INST: return true; 2188 default: return false; 2189 } 2190 } 2191 2192 std::string type_xfix(macro_type_t type, bool prefix) const 2193 { 2194 switch(type) 2195 { 2196 case MT_REG_ADDR: return prefix ? "" : "_ADDR"; 2197 case MT_REG_VAR: return prefix ? "" : ""; 2198 case MT_FIELD_BP: return prefix ? "BP_" : ""; 2199 case MT_FIELD_BM: return prefix ? "BM_" : ""; 2200 case MT_FIELD_BV: return prefix ? "BV_" : ""; 2201 case MT_FIELD_BF: return prefix ? "BF_" : ""; 2202 case MT_FIELD_BFM: return prefix ? "BFM_" : ""; 2203 case MT_FIELD_BFV: return prefix ? "BF_" : "_V"; 2204 case MT_FIELD_BFMV: return prefix ? "BFM_" : "_V"; 2205 default: return "<xfix>"; 2206 } 2207 } 2208 2209 std::string variant_xfix(const std::string& variant, bool prefix) const 2210 { 2211 return "<variant>"; 2212 } 2213 2214 std::string inst_prefix(const node_inst_t& inst) const 2215 { 2216 /* separate blocks with _: block_reg */ 2217 return "_"; 2218 } 2219 2220 std::string field_prefix() const 2221 { 2222 /* separate fields with _: block_reg_field */ 2223 return "_"; 2224 } 2225 2226 std::string enum_prefix() const 2227 { 2228 /* separate enums with __: block_reg_field__enum */ 2229 return "__"; 2230 } 2231 2232 std::string enum_name(const enum_ref_t& enum_) const 2233 { 2234 return enum_.get()->name; 2235 } 2236 2237 access_type_t register_access(const std::string& variant, access_t access) const 2238 { 2239 return AT_RW; 2240 } 2241 2242 bool has_sct() const 2243 { 2244 return false; 2245 } 2246 2247 std::string sct_variant(macro_name_t name) const 2248 { 2249 return "<variant>"; 2250 } 2251}; 2252 2253/** 2254 * Generator: cortex_m 2255 */ 2256class cortex_m_generator : public common_generator 2257{ 2258 bool has_support_macros() const 2259 { 2260 return true; 2261 } 2262 2263 bool has_selectors() const 2264 { 2265 return m_soc.size() >= 2; 2266 } 2267 2268 bool has_offsets() const 2269 { 2270 return false; 2271 } 2272 2273 std::string selector_soc_dir(const soc_ref_t& ref) const 2274 { 2275 return ref.get()->name; 2276 } 2277 2278 std::string selector_include_header() const 2279 { 2280 return "select.h"; 2281 } 2282 2283 std::string selector_soc_macro(const soc_ref_t& ref) const 2284 { 2285 return toupper(ref.get()->name) + "_INCLUDE"; 2286 } 2287 2288 std::string register_header(const node_inst_t& inst) const 2289 { 2290 /* one register header per top-level block */ 2291 if(inst.is_root()) 2292 return "<error>"; 2293 if(inst.parent().is_root()) 2294 return tolower(inst.node().name()) + ".h"; 2295 else 2296 return register_header(inst.parent()); 2297 } 2298 2299 std::string header_include_guard(const std::string& filename) 2300 { 2301 // Replace the default include guard to prevent conflicts with 2302 // other SoC-specific headergen-generated files 2303 std::string guard = "__ARM_CORTEX_M_" + toupper(filename) + "__"; 2304 for(size_t i = 0; i < guard.size(); i++) 2305 if(!isalnum(guard[i])) 2306 guard[i] = '_'; 2307 return guard; 2308 } 2309 2310 std::string macro_name(macro_name_t macro, bool relative) const 2311 { 2312 switch(macro) 2313 { 2314 case MN_REG_READ: return "cm_read"; 2315 case MN_FIELD_READ: return "cm_readf"; 2316 case MN_FIELD_READX: return "cm_vreadf"; 2317 case MN_REG_WRITE: return "cm_write"; 2318 case MN_FIELD_WRITE: return "cm_writef"; 2319 case MN_FIELD_OVERWRITE: return "cm_overwritef"; 2320 case MN_FIELD_WRITEX: return "cm_vwritef"; 2321 case MN_FIELD_SET: return "cm_setf"; 2322 case MN_FIELD_CLEAR: return "cm_clrf"; 2323 case MN_FIELD_OR: return "cm_orf"; 2324 case MN_FIELD_OR_MASK: return "__cm_orfm"; // internal macro 2325 case MN_MASK_OR: return "cm_orm"; 2326 case MN_GET_VARIANT: return "__cm_variant"; // internal macro 2327 case MN_VARIABLE: return "cm_reg"; 2328 default: return "<macro_name>"; 2329 } 2330 } 2331 2332 std::string macro_header() const 2333 { 2334 return "macro.h"; 2335 } 2336 2337 bool register_flag(const node_inst_t& inst, register_flag_t flag) const 2338 { 2339 /* make everything parametrized */ 2340 switch(flag) 2341 { 2342 case RF_GENERATE_ALL_INST: return false; 2343 case RF_GENERATE_PARAM_INST: return true; 2344 default: return false; 2345 } 2346 } 2347 2348 std::string type_xfix(macro_type_t type, bool prefix) const 2349 { 2350 switch(type) 2351 { 2352 case MT_REG_ADDR: return prefix ? "CMA_" : ""; 2353 case MT_REG_TYPE: return prefix ? "CMT_" : ""; 2354 case MT_REG_NAME: return prefix ? "CMN_" : ""; 2355 case MT_REG_VAR: return prefix ? "REG_" : ""; 2356 case MT_FIELD_BP: return prefix ? "BP_" : ""; 2357 case MT_FIELD_BM: return prefix ? "BM_" : ""; 2358 case MT_FIELD_BV: return prefix ? "BV_" : ""; 2359 case MT_FIELD_BF: return prefix ? "BF_" : ""; 2360 case MT_FIELD_BFM: return prefix ? "BFM_" : ""; 2361 case MT_FIELD_BFV: return prefix ? "BF_" : "_V"; 2362 case MT_FIELD_BFMV: return prefix ? "BFM_" : "_V"; 2363 case MT_IO_TYPE: return prefix ? "CMIO_" : ""; 2364 default: return "<xfix>"; 2365 } 2366 } 2367 2368 std::string variant_xfix(const std::string& variant, bool prefix) const 2369 { 2370 return "<variant>"; 2371 } 2372 2373 std::string inst_prefix(const node_inst_t& inst) const 2374 { 2375 /* separate blocks with _: block_reg */ 2376 return "_"; 2377 } 2378 2379 std::string field_prefix() const 2380 { 2381 /* separate fields with _: block_reg_field */ 2382 return "_"; 2383 } 2384 2385 std::string enum_prefix() const 2386 { 2387 /* separate enums with __: block_reg_field__enum */ 2388 return "__"; 2389 } 2390 2391 std::string enum_name(const enum_ref_t& enum_) const 2392 { 2393 return enum_.get()->name; 2394 } 2395 2396 access_type_t register_access(const std::string& variant, access_t access) const 2397 { 2398 if(access == WRITE_ONLY) 2399 return AT_WO; 2400 else if(access == READ_ONLY) 2401 return AT_RO; 2402 else 2403 return AT_RW; 2404 } 2405 2406 bool has_sct() const 2407 { 2408 return false; 2409 } 2410 2411 std::string sct_variant(macro_name_t name) const 2412 { 2413 return "<variant>"; 2414 } 2415}; 2416 2417/** 2418 * Generator: st 2419 */ 2420 2421class st_generator : public common_generator 2422{ 2423 bool has_support_macros() const 2424 { 2425 return true; 2426 } 2427 2428 bool has_selectors() const 2429 { 2430 return m_soc.size() >= 2; 2431 } 2432 2433 bool has_offsets() const 2434 { 2435 return true; 2436 } 2437 2438 std::string selector_soc_dir(const soc_ref_t& ref) const 2439 { 2440 return ref.get()->name; 2441 } 2442 2443 std::string selector_include_header() const 2444 { 2445 return "select.h"; 2446 } 2447 2448 std::string selector_soc_macro(const soc_ref_t& ref) const 2449 { 2450 return toupper(ref.get()->name) + "_INCLUDE"; 2451 } 2452 2453 std::string register_header(const node_inst_t& inst) const 2454 { 2455 /* one register header per top-level block */ 2456 if(inst.is_root()) 2457 return "<error>"; 2458 if(inst.parent().is_root()) 2459 return tolower(inst.node().name()) + ".h"; 2460 else 2461 return register_header(inst.parent()); 2462 } 2463 2464 std::string macro_name(macro_name_t macro, bool relative) const 2465 { 2466 switch(macro) 2467 { 2468 case MN_REG_READ: return relative ? "st_readl" : "st_read"; 2469 case MN_FIELD_READ: return relative ? "st_readlf" : "st_readf"; 2470 case MN_FIELD_READX: return "st_vreadf"; 2471 case MN_REG_WRITE: return relative ? "st_writel" : "st_write"; 2472 case MN_FIELD_WRITE: return relative ? "st_writelf" : "st_writef"; 2473 case MN_FIELD_OVERWRITE: return relative ? "st_overwritelf" : "st_overwritef"; 2474 case MN_FIELD_WRITEX: return "st_vwritef"; 2475 case MN_FIELD_SET: return relative ? "st_setlf" : "st_setf"; 2476 case MN_FIELD_CLEAR: return relative ? "st_clrlf" : "st_clrf"; 2477 case MN_FIELD_OR: return "st_orf"; 2478 case MN_FIELD_OR_MASK: return "__st_orfm"; // internal macro 2479 case MN_MASK_OR: return "st_orm"; 2480 case MN_GET_VARIANT: return "__st_variant"; // internal macro 2481 case MN_VARIABLE: return relative ? "st_regl" : "st_reg"; 2482 default: return "<macro_name>"; 2483 } 2484 } 2485 2486 std::string macro_header() const 2487 { 2488 return "macro.h"; 2489 } 2490 2491 bool register_flag(const node_inst_t& inst, register_flag_t flag) const 2492 { 2493 /* make everything parametrized */ 2494 switch(flag) 2495 { 2496 case RF_GENERATE_ALL_INST: return false; 2497 case RF_GENERATE_PARAM_INST: return true; 2498 default: return false; 2499 } 2500 } 2501 2502 std::string type_xfix(macro_type_t type, bool prefix) const 2503 { 2504 switch(type) 2505 { 2506 case MT_NODE_ADDR: /* fallthrough */ 2507 case MT_REG_ADDR: return prefix ? "STA_" : ""; 2508 case MT_REG_OFFSET: return prefix ? "STO_" : ""; 2509 case MT_REG_TYPE: return prefix ? "STT_" : ""; 2510 case MT_REG_NAME: return prefix ? "STN_" : ""; 2511 case MT_REG_VAR: return prefix ? "REG_" : ""; 2512 case MT_FIELD_BP: return prefix ? "BP_" : ""; 2513 case MT_FIELD_BM: return prefix ? "BM_" : ""; 2514 case MT_FIELD_BV: return prefix ? "BV_" : ""; 2515 case MT_FIELD_BF: return prefix ? "BF_" : ""; 2516 case MT_FIELD_BFM: return prefix ? "BFM_" : ""; 2517 case MT_FIELD_BFV: return prefix ? "BF_" : "_V"; 2518 case MT_FIELD_BFMV: return prefix ? "BFM_" : "_V"; 2519 case MT_IO_TYPE: return prefix ? "STIO_" : ""; 2520 default: return "<xfix>"; 2521 } 2522 } 2523 2524 std::string variant_xfix(const std::string& variant, bool prefix) const 2525 { 2526 /* variant X -> reg_X */ 2527 if(prefix) 2528 return ""; 2529 else 2530 return "_" + toupper(variant); 2531 } 2532 2533 std::string inst_prefix(const node_inst_t& inst) const 2534 { 2535 /* separate blocks with _: block_reg */ 2536 return "_"; 2537 } 2538 2539 std::string field_prefix() const 2540 { 2541 /* separate fields with _: block_reg_field */ 2542 return "_"; 2543 } 2544 2545 std::string enum_prefix() const 2546 { 2547 /* separate enums with __: block_reg_field__enum */ 2548 return "__"; 2549 } 2550 2551 std::string enum_name(const enum_ref_t& enum_) const 2552 { 2553 return enum_.get()->name; 2554 } 2555 2556 access_type_t register_access(const std::string& variant, access_t access) const 2557 { 2558 if(access == WRITE_ONLY) 2559 return AT_WO; 2560 else if(access == READ_ONLY) 2561 return AT_RO; 2562 else 2563 return AT_RW; 2564 } 2565 2566 bool has_sct() const 2567 { 2568 return false; 2569 } 2570 2571 std::string sct_variant(macro_name_t name) const 2572 { 2573 return "<variant>"; 2574 } 2575}; 2576 2577/** 2578 * Driver 2579 */ 2580 2581abstract_generator *get_generator(const std::string& name) 2582{ 2583 if(name == "jz") 2584 return new jz_generator(); 2585 else if(name == "imx") 2586 return new imx_generator(); 2587 else if(name == "atj") 2588 return new atj_generator(); 2589 else if(name == "cortex_m") 2590 return new cortex_m_generator(); 2591 else if(name == "st") 2592 return new st_generator(); 2593 else 2594 return 0; 2595} 2596 2597void usage() 2598{ 2599 printf("usage: headergen [options] <desc files...>\n"); 2600 printf("options:\n"); 2601 printf(" -?/--help Dispaly this help\n"); 2602 printf(" -g/--generator <gen> Select generator (jz, imx, atj, cortex_m, st)\n"); 2603 printf(" -o/--outdir <dir> Output directory\n"); 2604 exit(1); 2605} 2606 2607int main(int argc, char **argv) 2608{ 2609 char *generator_name = NULL; 2610 char *outdir = NULL; 2611 if(argc <= 1) 2612 usage(); 2613 2614 while(1) 2615 { 2616 static struct option long_options[] = 2617 { 2618 {"help", no_argument, 0, '?'}, 2619 {"generator", required_argument, 0, 'g'}, 2620 {"outdir", required_argument, 0, 'o'}, 2621 {0, 0, 0, 0} 2622 }; 2623 2624 int c = getopt_long(argc, argv, "?g:o:", long_options, NULL); 2625 if(c == -1) 2626 break; 2627 switch(c) 2628 { 2629 case -1: 2630 break; 2631 case '?': 2632 usage(); 2633 break; 2634 case 'g': 2635 generator_name = optarg; 2636 break; 2637 case 'o': 2638 outdir = optarg; 2639 break; 2640 default: 2641 abort(); 2642 } 2643 } 2644 if(argc == optind) 2645 { 2646 printf("You need at least one description file\n"); 2647 return 3; 2648 } 2649 if(outdir == 0) 2650 { 2651 printf("You need to select an output directory\n"); 2652 return 4; 2653 } 2654 if(generator_name == 0) 2655 { 2656 printf("You need to select a generator\n"); 2657 return 1; 2658 } 2659 abstract_generator *gen = get_generator(generator_name); 2660 if(gen == 0) 2661 { 2662 printf("Unknown generator name '%s'\n", generator_name); 2663 return 2; 2664 } 2665 2666 gen->set_output_dir(outdir); 2667 for(int i = optind; i < argc; i++) 2668 { 2669 error_context_t ctx; 2670 soc_t s; 2671 bool ret = parse_xml(argv[i], s, ctx); 2672 if(ctx.count() != 0) 2673 printf("In file %s:\n", argv[i]); 2674 print_context(ctx); 2675 if(!ret) 2676 { 2677 printf("Cannot parse file '%s'\n", argv[i]); 2678 return 1; 2679 } 2680 gen->add_soc(s); 2681 } 2682 error_context_t ctx; 2683 bool ret = gen->generate(ctx); 2684 print_context(ctx); 2685 if(!ret) 2686 { 2687 printf("Cannot generate headers\n"); 2688 return 5; 2689 } 2690 2691 return 0; 2692}