URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/or1ksim
- from Rev 220 to Rev 224
- ↔ Reverse comparison
Rev 220 → Rev 224
/sim-config.h
252,12 → 252,12
/*! Enum of all possible paramter types */ |
enum param_t |
{ |
paramt_none = 0, /* No parameter */ |
paramt_str, /* String parm enclosed in double quotes (") */ |
paramt_word, /* String parm NOT enclosed in double quotes */ |
paramt_int, /* Integer parameter */ |
paramt_longlong, /* Long long int parameter */ |
paramt_addr /* Address parameter */ |
PARAMT_NONE = 0, /* No parameter */ |
PARAMT_STR, /* String parm enclosed in double quotes (") */ |
PARAMT_WORD, /* String parm NOT enclosed in double quotes */ |
PARAMT_INT, /* Integer parameter */ |
PARAMT_LONGLONG, /* Long long int parameter */ |
PARAMT_ADDR /* Address parameter */ |
}; |
|
/* Generic structure for a configuration section */ |
/debug/debug-unit.c
1103,12 → 1103,12
{ |
struct config_section *sec = reg_config_sec ("debug", NULL, NULL); |
|
reg_config_param (sec, "enabled", paramt_int, debug_enabled); |
reg_config_param (sec, "gdb_enabled", paramt_int, debug_gdb_enabled); |
reg_config_param (sec, "rsp_enabled", paramt_int, debug_rsp_enabled); |
reg_config_param (sec, "server_port", paramt_int, debug_server_port); |
reg_config_param (sec, "rsp_port", paramt_int, debug_rsp_port); |
reg_config_param (sec, "vapi_id", paramt_int, debug_vapi_id); |
reg_config_param (sec, "enabled", PARAMT_INT, debug_enabled); |
reg_config_param (sec, "gdb_enabled", PARAMT_INT, debug_gdb_enabled); |
reg_config_param (sec, "rsp_enabled", PARAMT_INT, debug_rsp_enabled); |
reg_config_param (sec, "server_port", PARAMT_INT, debug_server_port); |
reg_config_param (sec, "rsp_port", PARAMT_INT, debug_rsp_port); |
reg_config_param (sec, "vapi_id", PARAMT_INT, debug_vapi_id); |
|
} /* reg_debug_sec () */ |
|
/cpu/or1k/spr-defs.h
94,6 → 94,7
#define SPR_EEAR_LAST (SPRGROUP_SYS + 63) |
#define SPR_ESR_BASE (SPRGROUP_SYS + 64) |
#define SPR_ESR_LAST (SPRGROUP_SYS + 79) |
#define SPR_GPR_BASE (SPRGROUP_SYS + 1024) |
|
/* Data MMU group */ |
#define SPR_DMMUCR (SPRGROUP_DMMU + 0) |
/configure.ac
28,7 → 28,7
|
# Use a full version number (x.y.z, possibly with "rcn" as a suffix) when |
# preparing a release, otherwise use a the date version (yyyy-mm-dd). |
AC_INIT([or1ksim], [2010-07-23], [openrisc@opencores.org]) |
AC_INIT([or1ksim], [2010-07-30], [openrisc@opencores.org]) |
AC_CONFIG_MACRO_DIR([m4]) |
|
# Generically use extensions such as _GNU_SOURCE if available. |
/cache/dcache-model.c
522,13 → 522,13
{ |
struct config_section *sec = reg_config_sec ("dc", NULL, NULL); |
|
reg_config_param (sec, "enabled", paramt_int, dc_enabled); |
reg_config_param (sec, "nsets", paramt_int, dc_nsets); |
reg_config_param (sec, "nways", paramt_int, dc_nways); |
reg_config_param (sec, "blocksize", paramt_int, dc_blocksize); |
reg_config_param (sec, "ustates", paramt_int, dc_ustates); |
reg_config_param (sec, "load_hitdelay", paramt_int, dc_load_hitdelay); |
reg_config_param (sec, "load_missdelay", paramt_int, dc_load_missdelay); |
reg_config_param (sec, "store_hitdelay", paramt_int, dc_store_hitdelay); |
reg_config_param (sec, "store_missdelay", paramt_int, dc_store_missdelay); |
reg_config_param (sec, "enabled", PARAMT_INT, dc_enabled); |
reg_config_param (sec, "nsets", PARAMT_INT, dc_nsets); |
reg_config_param (sec, "nways", PARAMT_INT, dc_nways); |
reg_config_param (sec, "blocksize", PARAMT_INT, dc_blocksize); |
reg_config_param (sec, "ustates", PARAMT_INT, dc_ustates); |
reg_config_param (sec, "load_hitdelay", PARAMT_INT, dc_load_hitdelay); |
reg_config_param (sec, "load_missdelay", PARAMT_INT, dc_load_missdelay); |
reg_config_param (sec, "store_hitdelay", PARAMT_INT, dc_store_hitdelay); |
reg_config_param (sec, "store_missdelay", PARAMT_INT, dc_store_missdelay); |
} |
/cache/icache-model.c
512,11 → 512,11
struct config_section *sec = |
reg_config_sec ("ic", ic_start_sec, ic_end_sec); |
|
reg_config_param (sec, "enabled", paramt_int, ic_enabled); |
reg_config_param (sec, "nsets", paramt_int, ic_nsets); |
reg_config_param (sec, "nways", paramt_int, ic_nways); |
reg_config_param (sec, "blocksize", paramt_int, ic_blocksize); |
reg_config_param (sec, "ustates", paramt_int, ic_ustates); |
reg_config_param (sec, "missdelay", paramt_int, ic_missdelay); |
reg_config_param (sec, "hitdelay", paramt_int, ic_hitdelay); |
reg_config_param (sec, "enabled", PARAMT_INT, ic_enabled); |
reg_config_param (sec, "nsets", PARAMT_INT, ic_nsets); |
reg_config_param (sec, "nways", PARAMT_INT, ic_nways); |
reg_config_param (sec, "blocksize", PARAMT_INT, ic_blocksize); |
reg_config_param (sec, "ustates", PARAMT_INT, ic_ustates); |
reg_config_param (sec, "missdelay", PARAMT_INT, ic_missdelay); |
reg_config_param (sec, "hitdelay" , PARAMT_INT, ic_hitdelay); |
} |
/doc/or1ksim.info
699,7 → 699,7
through the `-f' parameter to the Or1ksim command, or passed as a |
string when initializing the Or1ksim library. If no file is specified, |
the default `sim.cfg' is used. The file is looked for first in the |
current directory, then in the `$HOME/.or1k' directory of the user. |
current directory, then in the `$HOME/.or1ksim' directory of the user. |
|
* Menu: |
|
730,10 → 730,6
The configuration file may include C style comments (i.e. delimited by |
`/*' and `*/'). |
|
Configure files may be included, using |
|
include FILENAME_TO_INCLUDE |
|
|
File: or1ksim.info, Node: Configuration File Syntax, Prev: Configuration File Preprocessing, Up: Configuration File Format |
|
4338,43 → 4334,43
Node: Memory Profiling Utility15815 |
Node: Simulator Library17180 |
Node: Configuration24958 |
Node: Configuration File Format25567 |
Node: Configuration File Preprocessing25859 |
Node: Configuration File Syntax26230 |
Node: Simulator Configuration29015 |
Node: Simulator Behavior29306 |
Node: Verification API Configuration33835 |
Node: CUC Configuration35775 |
Node: Core OpenRISC Configuration37692 |
Node: CPU Configuration38194 |
Node: Memory Configuration42312 |
Node: Memory Management Configuration48770 |
Node: Cache Configuration51147 |
Node: Interrupt Configuration53533 |
Node: Power Management Configuration54269 |
Node: Branch Prediction Configuration55546 |
Node: Debug Interface Configuration56906 |
Node: Peripheral Configuration61126 |
Node: Memory Controller Configuration61752 |
Node: UART Configuration65166 |
Node: DMA Configuration68685 |
Node: Ethernet Configuration70552 |
Node: GPIO Configuration74528 |
Node: Display Interface Configuration76161 |
Node: Frame Buffer Configuration78470 |
Node: Keyboard Configuration80334 |
Node: Disc Interface Configuration82572 |
Node: Generic Peripheral Configuration87515 |
Node: Interactive Command Line89810 |
Node: Verification API96784 |
Node: Code Internals101214 |
Node: Coding Conventions101797 |
Node: Global Data Structures106224 |
Node: Concepts108881 |
Ref: Output Redirection109026 |
Node: Internal Debugging109565 |
Node: Regression Testing110089 |
Node: GNU Free Documentation License113884 |
Node: Index136291 |
Node: Configuration File Format25570 |
Node: Configuration File Preprocessing25862 |
Node: Configuration File Syntax26159 |
Node: Simulator Configuration28944 |
Node: Simulator Behavior29235 |
Node: Verification API Configuration33764 |
Node: CUC Configuration35704 |
Node: Core OpenRISC Configuration37621 |
Node: CPU Configuration38123 |
Node: Memory Configuration42241 |
Node: Memory Management Configuration48699 |
Node: Cache Configuration51076 |
Node: Interrupt Configuration53462 |
Node: Power Management Configuration54198 |
Node: Branch Prediction Configuration55475 |
Node: Debug Interface Configuration56835 |
Node: Peripheral Configuration61055 |
Node: Memory Controller Configuration61681 |
Node: UART Configuration65095 |
Node: DMA Configuration68614 |
Node: Ethernet Configuration70481 |
Node: GPIO Configuration74457 |
Node: Display Interface Configuration76090 |
Node: Frame Buffer Configuration78399 |
Node: Keyboard Configuration80263 |
Node: Disc Interface Configuration82501 |
Node: Generic Peripheral Configuration87444 |
Node: Interactive Command Line89739 |
Node: Verification API96713 |
Node: Code Internals101143 |
Node: Coding Conventions101726 |
Node: Global Data Structures106153 |
Node: Concepts108810 |
Ref: Output Redirection108955 |
Node: Internal Debugging109494 |
Node: Regression Testing110018 |
Node: GNU Free Documentation License113813 |
Node: Index136220 |
|
End Tag Table |
/doc/or1ksim.texi
856,7 → 856,7
through the @code{-f} parameter to the @value{OR1KSIM} command, or passed as a |
string when initializing the @value{OR1KSIM} library. If no file is specified, |
the default @file{sim.cfg} is used. The file is looked for first in the |
current directory, then in the @file{$HOME/.or1k} directory of the user. |
current directory, then in the @file{$HOME/.or1ksim} directory of the user. |
|
@menu |
* Configuration File Format:: |
882,12 → 882,6
The configuration file may include C style comments (i.e. delimited by |
@code{/*} and @code{*/}). |
|
Configure files may be included, using |
|
@example |
include @var{filename_to_include} |
@end example |
|
@node Configuration File Syntax |
@subsection Configuration File Syntax |
|
/doc/version.texi
1,4 → 1,4
@set UPDATED 23 July 2010 |
@set UPDATED 26 July 2010 |
@set UPDATED-MONTH July 2010 |
@set EDITION 2010-07-23 |
@set VERSION 2010-07-23 |
/cuc/cuc.c
1181,10 → 1181,10
{ |
struct config_section *sec = reg_config_sec ("cuc", NULL, NULL); |
|
reg_config_param (sec, "memory_order", paramt_word, cuc_memory_order); |
reg_config_param (sec, "calling_convention", paramt_int, cuc_calling_conv); |
reg_config_param (sec, "enable_bursts", paramt_int, cuc_enable_bursts); |
reg_config_param (sec, "no_multicycle", paramt_int, cuc_no_multicycle); |
reg_config_param (sec, "timings_file", paramt_str, cuc_timings_fn); |
reg_config_param (sec, "timings_fn", paramt_str, cuc_timings_fn); |
reg_config_param (sec, "memory_order", PARAMT_WORD, cuc_memory_order); |
reg_config_param (sec, "calling_convention", PARAMT_INT, cuc_calling_conv); |
reg_config_param (sec, "enable_bursts", PARAMT_INT, cuc_enable_bursts); |
reg_config_param (sec, "no_multicycle", PARAMT_INT, cuc_no_multicycle); |
reg_config_param (sec, "timings_file", PARAMT_STR, cuc_timings_fn); |
reg_config_param (sec, "timings_fn", PARAMT_STR, cuc_timings_fn); |
} |
/or1ksim.h
63,8 → 63,6
|
int or1ksim_run (double duration); |
|
int or1ksim_step (); |
|
void or1ksim_reset_duration (double duration); |
|
void or1ksim_set_time_point (); |
92,23 → 90,28
int num_bits); |
|
/* Access to simulator state */ |
int or1ksim_read_mem (unsigned char *buf, |
unsigned int addr, |
int or1ksim_read_mem (unsigned int addr, |
unsigned char *buf, |
int len); |
|
int or1ksim_write_mem (unsigned char *buf, |
unsigned int addr, |
int or1ksim_write_mem (unsigned int addr, |
unsigned char *buf, |
int len); |
|
int or1ksim_read_reg (unsigned char *buf, |
int regnum, |
int len); |
int or1ksim_read_spr (int sprnum, |
unsigned int *sprval_ptr); |
|
int or1ksim_write_reg (unsigned char *buf, |
int regnum, |
int len); |
int or1ksim_write_spr (int sprnum, |
unsigned int sprval); |
|
int or1ksim_read_reg (int regnum, |
unsigned int *regval_ptr); |
|
int or1ksim_write_reg (int regnum, |
unsigned int regval); |
|
void or1ksim_set_stall_state (int state); |
|
#ifdef __cplusplus |
} |
#endif |
/NEWS
8,6 → 8,17
The library interface is extended to allow registers and memory to be written |
directly. This is to allow direct integration as a simulator in GDB. |
|
The "include" feature of configuration files (which never worked, but no one |
ever noticed) is dropped. |
|
If the configuration file is not found in the local directory, it is searched |
for in the ${HOME}/.or1ksim directory, then (for backwards compatibility) the |
${HOME}/.or1k directory. |
|
There is an option to collect statistics on instruction execution in binary |
form. |
|
|
The following bugs are fixed. |
* Bug 1797: Or1ksim does not compile with GCC 3.4.4 under Cygwin |
* Bug 1795: GDB breakpoints do not work with Icache enabled. |
/ChangeLog
2,6 → 2,82
|
* configure: Regenerated. |
* configure.ac: Version changed to current date. |
* config/dcache-model.c (reg_dc_sec): Upper case enumeration |
elements. |
* config/icache-model.c (reg_ic_sec): Upper case enumeration |
elements. |
* cpu/or1k/spr-defs.h <System control and status group>: Add |
SPR_GPR_BASE. |
* debug/debug-unit.c (reg_debug_sec): Upper case enumeration |
elements. |
* sim-config.h <enum param_t>: Upper case enumeration elements. |
* doc/or1ksim.texi: Delete reference to using include files. |
* cuc/cuc.c (reg_cuc_sec): Upper case enumeration elements. |
* or1ksim.h <or1ksim_read_mem, or1ksim_write_mem>: Argument order |
changed. |
<or1ksim_read_reg, or1ksim_write_reg>: Argument as value, not |
buffer. |
<or1ksim_read_spr, or1ksim_write_spr, or1ksim_set_stall_state>: |
Added. |
* NEWS: Updated with new features. |
* peripheral/gpio.c (reg_gpio_sec): Upper case enumeration |
elements. |
* peripheral/mc.c (reg_mc_sec): Upper case enumeration elements. |
* peripheral/generic.c (reg_generic_sec): Upper case enumeration |
elements. |
* peripheral/eth.c (reg_eth_sec): Upper case enumeration |
elements. |
* peripheral/kbd.c (reg_kbd_sec): Upper case enumeration |
elements. |
* peripheral/fb.c (reg_fb_sec): Upper case enumeration elements. |
* peripheral/dma.c (reg_dma_sec): Upper case enumeration |
elements. |
* peripheral/ata.c (reg_ata_sec): Upper case enumeration |
elements. |
* peripheral/memory.c (reg_memory_sec): Upper case enumeration |
elements. |
* peripheral/vga.c (reg_vga_sec): Upper case enumeration |
elements. |
* peripheral/uart.c (reg_uart_sec): Upper case enumeration |
elements. |
* mmu/dmmu.c (reg_dmmu_sec): Upper case enumeration elements. |
* mmu/immu.c (reg_immu_sec): Upper case enumeration elements. |
* vapi/vapi.c (reg_vapi_sec): Upper case enumeration elements. |
* bpb/branch-predict.c (reg_bpb_sec): Upper case enumeration |
elements. |
* cpu-config.c (reg_cpu_sec): Upper case enumeration elements. |
* libtoplevel.c: Include debug-unit.h, spr-defs.h and sprs.h |
headers. |
(or1ksim_step): Deleted. |
(or1ksim_read_mem, or1ksim_write_mem): Argument order |
changed. |
(or1ksim_read_reg, or1ksim_write_reg): Argument as value, not |
buffer. Mapped to SPR read/write calls. |
(or1ksim_read_spr, or1ksim_write_spr, or1ksim_set_stall_state): |
Created. |
* pic/pic.c (reg_pic_sec): Upper case enumeration elements. |
* pm/pm.c (reg_pm_sec): Upper case enumeration elements. |
* sim-config.c <cur_sections>: Global variable deleted and |
replaced by local arguments. |
<section_master_list>: Renamed from sections. |
<read_script_file>: Forward declaration deleted. |
(lookup_section, lookup_param): Created. |
(set_config_param): Renamed from switch_param. Simplified - no |
preceding blanks and string and word representations are |
identical. |
(next_word, next_lexeme): Created. |
(read_script_file): Also search ~/.or1ksim. Use new functions to |
get lexemes and to lookup sections and parameters. |
(alloc_memory_block): Created. |
(parse_args): New arguments -q/--quiet, --report-memory-errors, |
-m/--memory. No use of sim.cfg as default config file. |
(reg_sim_sec): Upper case enumeration elements. |
(set_config): Use new section and parameter lookup functions. |
|
2010-06-31 Jeremy Bennett <jeremy.bennett@embecosm.co> |
|
* configure: Regenerated. |
* configure.ac: Version changed to current date. |
* cpu/common/abstract.c (setsim_mem32, setsim_mem16, setsim_mem8) |
(evalsim_mem32, evalsim_mem16, evalsim_mem8): Only report out of |
memory writes if --report-memory-errors is set. |
/peripheral/gpio.c
425,9 → 425,9
struct config_section *sec = |
reg_config_sec ("gpio", gpio_sec_start, gpio_sec_end); |
|
reg_config_param (sec, "enabled", paramt_int, gpio_enabled); |
reg_config_param (sec, "baseaddr", paramt_addr, gpio_baseaddr); |
reg_config_param (sec, "irq", paramt_int, gpio_irq); |
reg_config_param (sec, "vapi_id", paramt_int, gpio_base_vapi_id); |
reg_config_param (sec, "base_vapi_id", paramt_int, gpio_base_vapi_id); |
reg_config_param (sec, "enabled", PARAMT_INT, gpio_enabled); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, gpio_baseaddr); |
reg_config_param (sec, "irq", PARAMT_INT, gpio_irq); |
reg_config_param (sec, "vapi_id", PARAMT_INT, gpio_base_vapi_id); |
reg_config_param (sec, "base_vapi_id", PARAMT_INT, gpio_base_vapi_id); |
} |
/peripheral/mc.c
436,8 → 436,8
struct config_section *sec = |
reg_config_sec ("mc", mc_sec_start, mc_sec_end); |
|
reg_config_param (sec, "enabled", paramt_int, mc_enabled); |
reg_config_param (sec, "baseaddr", paramt_addr, mc_baseaddr); |
reg_config_param (sec, "POC", paramt_int, mc_poc); |
reg_config_param (sec, "index", paramt_int, mc_index); |
reg_config_param (sec, "enabled", PARAMT_INT, mc_enabled); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, mc_baseaddr); |
reg_config_param (sec, "POC", PARAMT_INT, mc_poc); |
reg_config_param (sec, "index", PARAMT_INT, mc_index); |
} |
/peripheral/generic.c
693,12 → 693,12
generic_sec_start, |
generic_sec_end); |
|
reg_config_param (sec, "enabled", paramt_int, generic_enabled); |
reg_config_param (sec, "byte_enabled", paramt_int, generic_byte_enabled); |
reg_config_param (sec, "hw_enabled", paramt_int, generic_hw_enabled); |
reg_config_param (sec, "word_enabled", paramt_int, generic_word_enabled); |
reg_config_param (sec, "name", paramt_str, generic_name); |
reg_config_param (sec, "baseaddr", paramt_addr, generic_baseaddr); |
reg_config_param (sec, "size", paramt_int, generic_size); |
reg_config_param (sec, "enabled", PARAMT_INT, generic_enabled); |
reg_config_param (sec, "byte_enabled", PARAMT_INT, generic_byte_enabled); |
reg_config_param (sec, "hw_enabled", PARAMT_INT, generic_hw_enabled); |
reg_config_param (sec, "word_enabled", PARAMT_INT, generic_word_enabled); |
reg_config_param (sec, "name", PARAMT_STR, generic_name); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, generic_baseaddr); |
reg_config_param (sec, "size", PARAMT_INT, generic_size); |
|
} /* reg_generic_sec */ |
/peripheral/eth.c
1306,17 → 1306,17
struct config_section *sec = |
reg_config_sec ("ethernet", eth_sec_start, eth_sec_end); |
|
reg_config_param (sec, "enabled", paramt_int, eth_enabled); |
reg_config_param (sec, "baseaddr", paramt_addr, eth_baseaddr); |
reg_config_param (sec, "dma", paramt_int, eth_dma); |
reg_config_param (sec, "irq", paramt_int, eth_irq); |
reg_config_param (sec, "rtx_type", paramt_int, eth_rtx_type); |
reg_config_param (sec, "rx_channel", paramt_int, eth_rx_channel); |
reg_config_param (sec, "tx_channel", paramt_int, eth_tx_channel); |
reg_config_param (sec, "rxfile", paramt_str, eth_rxfile); |
reg_config_param (sec, "txfile", paramt_str, eth_txfile); |
reg_config_param (sec, "sockif", paramt_str, eth_sockif); |
reg_config_param (sec, "vapi_id", paramt_int, eth_vapi_id); |
reg_config_param (sec, "enabled", PARAMT_INT, eth_enabled); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, eth_baseaddr); |
reg_config_param (sec, "dma", PARAMT_INT, eth_dma); |
reg_config_param (sec, "irq", PARAMT_INT, eth_irq); |
reg_config_param (sec, "rtx_type", PARAMT_INT, eth_rtx_type); |
reg_config_param (sec, "rx_channel", PARAMT_INT, eth_rx_channel); |
reg_config_param (sec, "tx_channel", PARAMT_INT, eth_tx_channel); |
reg_config_param (sec, "rxfile", PARAMT_STR, eth_rxfile); |
reg_config_param (sec, "txfile", PARAMT_STR, eth_txfile); |
reg_config_param (sec, "sockif", PARAMT_STR, eth_sockif); |
reg_config_param (sec, "vapi_id", PARAMT_INT, eth_vapi_id); |
|
} /* reg_ethernet_sec() */ |
|
/peripheral/ps2kbd.c
757,8 → 757,8
struct config_section *sec = |
reg_config_sec ("kbd", kbd_sec_start, kbd_sec_end); |
|
reg_config_param (sec, "baseaddr", paramt_addr, kbd_baseaddr); |
reg_config_param (sec, "enabled", paramt_int, kbd_enabled); |
reg_config_param (sec, "irq", paramt_int, kbd_irq); |
reg_config_param (sec, "rxfile", paramt_str, kbd_rxfile); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, kbd_baseaddr); |
reg_config_param (sec, "enabled", PARAMT_INT, kbd_enabled); |
reg_config_param (sec, "irq", PARAMT_INT, kbd_irq); |
reg_config_param (sec, "rxfile", PARAMT_STR, kbd_rxfile); |
} |
/peripheral/fb.c
547,9 → 547,9
struct config_section *sec = |
reg_config_sec ("fb", fb_sec_start, fb_sec_end); |
|
reg_config_param (sec, "baseaddr", paramt_addr, fb_baseaddr); |
reg_config_param (sec, "enabled", paramt_int, fb_enabled); |
reg_config_param (sec, "refresh_rate", paramt_int, fb_refresh_rate); |
reg_config_param (sec, "txfile", paramt_str, fb_filename); |
reg_config_param (sec, "filename", paramt_str, fb_filename); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, fb_baseaddr); |
reg_config_param (sec, "enabled", PARAMT_INT, fb_enabled); |
reg_config_param (sec, "refresh_rate", PARAMT_INT, fb_refresh_rate); |
reg_config_param (sec, "txfile", PARAMT_STR, fb_filename); |
reg_config_param (sec, "filename", PARAMT_STR, fb_filename); |
} |
/peripheral/dma.c
652,8 → 652,8
struct config_section *sec = |
reg_config_sec ("dma", dma_sec_start, dma_sec_end); |
|
reg_config_param (sec, "enabled", paramt_int, dma_enabled); |
reg_config_param (sec, "baseaddr", paramt_addr, dma_baseaddr); |
reg_config_param (sec, "irq", paramt_int, dma_irq); |
reg_config_param (sec, "vapi_id", paramt_addr, dma_vapi_id); |
reg_config_param (sec, "enabled", PARAMT_INT, dma_enabled); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, dma_baseaddr); |
reg_config_param (sec, "irq", PARAMT_INT, dma_irq); |
reg_config_param (sec, "vapi_id", PARAMT_ADDR, dma_vapi_id); |
} |
/peripheral/atahost.c
710,31 → 710,31
struct config_section *sec = |
reg_config_sec ("ata", ata_sec_start, ata_sec_end); |
|
reg_config_param (sec, "enabled", paramt_int, ata_enabled); |
reg_config_param (sec, "baseaddr", paramt_addr, ata_baseaddr); |
reg_config_param (sec, "irq", paramt_int, ata_irq); |
reg_config_param (sec, "dev_id", paramt_int, ata_dev_id); |
reg_config_param (sec, "rev", paramt_int, ata_rev); |
reg_config_param (sec, "enabled", PARAMT_INT, ata_enabled); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, ata_baseaddr); |
reg_config_param (sec, "irq", PARAMT_INT, ata_irq); |
reg_config_param (sec, "dev_id", PARAMT_INT, ata_dev_id); |
reg_config_param (sec, "rev", PARAMT_INT, ata_rev); |
|
reg_config_param (sec, "pio_mode0_t1", paramt_int, ata_pio_mode0_t1); |
reg_config_param (sec, "pio_mode0_t2", paramt_int, ata_pio_mode0_t2); |
reg_config_param (sec, "pio_mode0_t4", paramt_int, ata_pio_mode0_t4); |
reg_config_param (sec, "pio_mode0_teoc", paramt_int, ata_pio_mode0_teoc); |
reg_config_param (sec, "pio_mode0_t1", PARAMT_INT, ata_pio_mode0_t1); |
reg_config_param (sec, "pio_mode0_t2", PARAMT_INT, ata_pio_mode0_t2); |
reg_config_param (sec, "pio_mode0_t4", PARAMT_INT, ata_pio_mode0_t4); |
reg_config_param (sec, "pio_mode0_teoc", PARAMT_INT, ata_pio_mode0_teoc); |
|
reg_config_param (sec, "dma_mode0_tm", paramt_int, ata_dma_mode0_tm); |
reg_config_param (sec, "dma_mode0_td", paramt_int, ata_dma_mode0_td); |
reg_config_param (sec, "dma_mode0_teoc", paramt_int, ata_dma_mode0_teoc); |
reg_config_param (sec, "dma_mode0_tm", PARAMT_INT, ata_dma_mode0_tm); |
reg_config_param (sec, "dma_mode0_td", PARAMT_INT, ata_dma_mode0_td); |
reg_config_param (sec, "dma_mode0_teoc", PARAMT_INT, ata_dma_mode0_teoc); |
|
reg_config_param (sec, "device", paramt_int, ata_start_device); |
reg_config_param (sec, "enddevice", paramt_int, ata_enddevice); |
reg_config_param (sec, "device", PARAMT_INT, ata_start_device); |
reg_config_param (sec, "enddevice", PARAMT_INT, ata_enddevice); |
|
reg_config_param (sec, "type", paramt_int, ata_type); |
reg_config_param (sec, "file", paramt_str, ata_file); |
reg_config_param (sec, "size", paramt_int, ata_size); |
reg_config_param (sec, "packet", paramt_int, ata_packet); |
reg_config_param (sec, "heads", paramt_int, ata_heads); |
reg_config_param (sec, "sectors", paramt_int, ata_sectors); |
reg_config_param (sec, "firmware", paramt_str, ata_firmware); |
reg_config_param (sec, "mwdma", paramt_int, ata_mwdma); |
reg_config_param (sec, "pio", paramt_int, ata_pio); |
reg_config_param (sec, "type", PARAMT_INT, ata_type); |
reg_config_param (sec, "file", PARAMT_STR, ata_file); |
reg_config_param (sec, "size", PARAMT_INT, ata_size); |
reg_config_param (sec, "packet", PARAMT_INT, ata_packet); |
reg_config_param (sec, "heads", PARAMT_INT, ata_heads); |
reg_config_param (sec, "sectors", PARAMT_INT, ata_sectors); |
reg_config_param (sec, "firmware", PARAMT_STR, ata_firmware); |
reg_config_param (sec, "mwdma", PARAMT_INT, ata_mwdma); |
reg_config_param (sec, "pio", PARAMT_INT, ata_pio); |
} |
/peripheral/memory.c
471,15 → 471,15
struct config_section *sec = reg_config_sec ("memory", memory_sec_start, |
memory_sec_end); |
|
reg_config_param (sec, "type", paramt_word, memory_type); |
reg_config_param (sec, "random_seed", paramt_int, memory_random_seed); |
reg_config_param (sec, "pattern", paramt_int, memory_pattern); |
reg_config_param (sec, "baseaddr", paramt_addr, memory_baseaddr); |
reg_config_param (sec, "size", paramt_int, memory_size); |
reg_config_param (sec, "name", paramt_str, memory_name); |
reg_config_param (sec, "ce", paramt_int, memory_ce); |
reg_config_param (sec, "mc", paramt_int, memory_mc); |
reg_config_param (sec, "delayr", paramt_int, memory_delayr); |
reg_config_param (sec, "delayw", paramt_int, memory_delayw); |
reg_config_param (sec, "log", paramt_str, memory_log); |
reg_config_param (sec, "type", PARAMT_WORD, memory_type); |
reg_config_param (sec, "random_seed", PARAMT_INT, memory_random_seed); |
reg_config_param (sec, "pattern", PARAMT_INT, memory_pattern); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, memory_baseaddr); |
reg_config_param (sec, "size", PARAMT_INT, memory_size); |
reg_config_param (sec, "name", PARAMT_STR, memory_name); |
reg_config_param (sec, "ce", PARAMT_INT, memory_ce); |
reg_config_param (sec, "mc", PARAMT_INT, memory_mc); |
reg_config_param (sec, "delayr", PARAMT_INT, memory_delayr); |
reg_config_param (sec, "delayw", PARAMT_INT, memory_delayw); |
reg_config_param (sec, "log", PARAMT_STR, memory_log); |
} |
/peripheral/vga.c
450,12 → 450,12
struct config_section *sec = |
reg_config_sec ("vga", vga_sec_start, vga_sec_end); |
|
reg_config_param (sec, "baseaddr", paramt_addr, vga_baseaddr); |
reg_config_param (sec, "enabled", paramt_int, vga_enabled); |
reg_config_param (sec, "irq", paramt_int, vga_irq); |
reg_config_param (sec, "refresh_rate", paramt_int, vga_refresh_rate); |
reg_config_param (sec, "txfile", paramt_str, vga_filename); |
reg_config_param (sec, "filename", paramt_str, vga_filename); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, vga_baseaddr); |
reg_config_param (sec, "enabled", PARAMT_INT, vga_enabled); |
reg_config_param (sec, "irq", PARAMT_INT, vga_irq); |
reg_config_param (sec, "refresh_rate", PARAMT_INT, vga_refresh_rate); |
reg_config_param (sec, "txfile", PARAMT_STR, vga_filename); |
reg_config_param (sec, "filename", PARAMT_STR, vga_filename); |
|
} /* reg_vga_sec() */ |
|
/peripheral/16450.c
1334,13 → 1334,13
struct config_section *sec = reg_config_sec ("uart", uart_sec_start, |
uart_sec_end); |
|
reg_config_param (sec, "enabled", paramt_int, uart_enabled); |
reg_config_param (sec, "baseaddr", paramt_addr, uart_baseaddr); |
reg_config_param (sec, "irq", paramt_int, uart_irq); |
reg_config_param (sec, "16550", paramt_int, uart_16550); |
reg_config_param (sec, "jitter", paramt_int, uart_jitter); |
reg_config_param (sec, "channel", paramt_str, uart_channel); |
reg_config_param (sec, "txfile", paramt_str, uart_newway); |
reg_config_param (sec, "rxfile", paramt_str, uart_newway); |
reg_config_param (sec, "vapi_id", paramt_int, uart_vapi_id); |
reg_config_param (sec, "enabled", PARAMT_INT, uart_enabled); |
reg_config_param (sec, "baseaddr", PARAMT_ADDR, uart_baseaddr); |
reg_config_param (sec, "irq", PARAMT_INT, uart_irq); |
reg_config_param (sec, "16550", PARAMT_INT, uart_16550); |
reg_config_param (sec, "jitter", PARAMT_INT, uart_jitter); |
reg_config_param (sec, "channel", PARAMT_STR, uart_channel); |
reg_config_param (sec, "txfile", PARAMT_STR, uart_newway); |
reg_config_param (sec, "rxfile", PARAMT_STR, uart_newway); |
reg_config_param (sec, "vapi_id", PARAMT_INT, uart_vapi_id); |
} |
/mmu/dmmu.c
558,12 → 558,12
struct config_section *sec = reg_config_sec ("dmmu", dmmu_start_sec, |
dmmu_end_sec); |
|
reg_config_param (sec, "enabled", paramt_int, dmmu_enabled); |
reg_config_param (sec, "nsets", paramt_int, dmmu_nsets); |
reg_config_param (sec, "nways", paramt_int, dmmu_nways); |
reg_config_param (sec, "pagesize", paramt_int, dmmu_pagesize); |
reg_config_param (sec, "entrysize", paramt_int, dmmu_entrysize); |
reg_config_param (sec, "ustates", paramt_int, dmmu_ustates); |
reg_config_param (sec, "hitdelay", paramt_int, dmmu_hitdelay); |
reg_config_param (sec, "missdelay", paramt_int, dmmu_missdelay); |
reg_config_param (sec, "enabled", PARAMT_INT, dmmu_enabled); |
reg_config_param (sec, "nsets", PARAMT_INT, dmmu_nsets); |
reg_config_param (sec, "nways", PARAMT_INT, dmmu_nways); |
reg_config_param (sec, "pagesize", PARAMT_INT, dmmu_pagesize); |
reg_config_param (sec, "entrysize", PARAMT_INT, dmmu_entrysize); |
reg_config_param (sec, "ustates", PARAMT_INT, dmmu_ustates); |
reg_config_param (sec, "hitdelay", PARAMT_INT, dmmu_hitdelay); |
reg_config_param (sec, "missdelay", PARAMT_INT, dmmu_missdelay); |
} |
/mmu/immu.c
530,12 → 530,12
struct config_section *sec = reg_config_sec ("immu", immu_start_sec, |
immu_end_sec); |
|
reg_config_param (sec, "enabled", paramt_int, immu_enabled); |
reg_config_param (sec, "nsets", paramt_int, immu_nsets); |
reg_config_param (sec, "nways", paramt_int, immu_nways); |
reg_config_param (sec, "pagesize", paramt_int, immu_pagesize); |
reg_config_param (sec, "entrysize", paramt_int, immu_entrysize); |
reg_config_param (sec, "ustates", paramt_int, immu_ustates); |
reg_config_param (sec, "missdelay", paramt_int, immu_missdelay); |
reg_config_param (sec, "hitdelay", paramt_int, immu_hitdelay); |
reg_config_param (sec, "enabled", PARAMT_INT, immu_enabled); |
reg_config_param (sec, "nsets", PARAMT_INT, immu_nsets); |
reg_config_param (sec, "nways", PARAMT_INT, immu_nways); |
reg_config_param (sec, "pagesize", PARAMT_INT, immu_pagesize); |
reg_config_param (sec, "entrysize", PARAMT_INT, immu_entrysize); |
reg_config_param (sec, "ustates", PARAMT_INT, immu_ustates); |
reg_config_param (sec, "missdelay", PARAMT_INT, immu_missdelay); |
reg_config_param (sec, "hitdelay", PARAMT_INT, immu_hitdelay); |
} |
/vapi/vapi.c
783,10 → 783,10
{ |
struct config_section *sec = reg_config_sec ("VAPI", NULL, NULL); |
|
reg_config_param (sec, "enabled", paramt_int, vapi_enabled); |
reg_config_param (sec, "server_port", paramt_int, vapi_server_port); |
reg_config_param (sec, "log_enabled", paramt_int, vapi_log_enabled); |
reg_config_param (sec, "hide_device_id", paramt_int, vapi_hide_device_id); |
reg_config_param (sec, "vapi_log_file", paramt_str, vapi_log_fn); |
reg_config_param (sec, "vapi_log_fn", paramt_str, vapi_log_fn); |
reg_config_param (sec, "enabled", PARAMT_INT, vapi_enabled); |
reg_config_param (sec, "server_port", PARAMT_INT, vapi_server_port); |
reg_config_param (sec, "log_enabled", PARAMT_INT, vapi_log_enabled); |
reg_config_param (sec, "hide_device_id", PARAMT_INT, vapi_hide_device_id); |
reg_config_param (sec, "vapi_log_file", PARAMT_STR, vapi_log_fn); |
reg_config_param (sec, "vapi_log_fn", PARAMT_STR, vapi_log_fn); |
} |
/bpb/branch-predict.c
299,10 → 299,10
{ |
struct config_section *sec = reg_config_sec ("bpb", NULL, NULL); |
|
reg_config_param (sec, "enabled", paramt_int, bpb_enabled); |
reg_config_param (sec, "btic", paramt_int, bpb_btic); |
reg_config_param (sec, "sbp_bnf_fwd", paramt_int, bpb_sbp_bnf_fwd); |
reg_config_param (sec, "sbp_bf_fwd", paramt_int, bpb_sbp_bf_fwd); |
reg_config_param (sec, "missdelay", paramt_int, bpb_missdelay); |
reg_config_param (sec, "hitdelay", paramt_int, bpb_hitdelay); |
reg_config_param (sec, "enabled", PARAMT_INT, bpb_enabled); |
reg_config_param (sec, "btic", PARAMT_INT, bpb_btic); |
reg_config_param (sec, "sbp_bnf_fwd", PARAMT_INT, bpb_sbp_bnf_fwd); |
reg_config_param (sec, "sbp_bf_fwd", PARAMT_INT, bpb_sbp_bf_fwd); |
reg_config_param (sec, "missdelay", PARAMT_INT, bpb_missdelay); |
reg_config_param (sec, "hitdelay", PARAMT_INT, bpb_hitdelay); |
} |
/cpu-config.c
39,7 → 39,7
#include "execute.h" |
|
|
#define WARNING(s) fprintf (stderr, "Warning: config.%s: %s\n", cur_section->name, (s)) |
#define WARNING(s) fprintf (stderr, "Warning: config.cpu: %s\n", (s)) |
|
/*---------------------------------------------------------------------------*/ |
/*!Set the CPU version |
226,16 → 226,16
{ |
struct config_section *sec = reg_config_sec ("cpu", NULL, NULL); |
|
reg_config_param (sec, "ver", paramt_int, cpu_ver); |
reg_config_param (sec, "cfg", paramt_int, cpu_cfg); |
reg_config_param (sec, "rev", paramt_int, cpu_rev); |
reg_config_param (sec, "upr", paramt_int, cpu_upr); |
reg_config_param (sec, "cfgr", paramt_int, cpu_cfgr); |
reg_config_param (sec, "sr", paramt_int, cpu_sr); |
reg_config_param (sec, "superscalar", paramt_int, cpu_superscalar); |
reg_config_param (sec, "hazards", paramt_int, cpu_hazards); |
reg_config_param (sec, "dependstats", paramt_int, cpu_dependstats); |
reg_config_param (sec, "sbuf_len", paramt_int, cpu_sbuf_len); |
reg_config_param (sec, "hardfloat", paramt_int, cpu_hardfloat); |
reg_config_param (sec, "ver", PARAMT_INT, cpu_ver); |
reg_config_param (sec, "cfg", PARAMT_INT, cpu_cfg); |
reg_config_param (sec, "rev", PARAMT_INT, cpu_rev); |
reg_config_param (sec, "upr", PARAMT_INT, cpu_upr); |
reg_config_param (sec, "cfgr", PARAMT_INT, cpu_cfgr); |
reg_config_param (sec, "sr", PARAMT_INT, cpu_sr); |
reg_config_param (sec, "superscalar", PARAMT_INT, cpu_superscalar); |
reg_config_param (sec, "hazards", PARAMT_INT, cpu_hazards); |
reg_config_param (sec, "dependstats", PARAMT_INT, cpu_dependstats); |
reg_config_param (sec, "sbuf_len", PARAMT_INT, cpu_sbuf_len); |
reg_config_param (sec, "hardfloat", PARAMT_INT, cpu_hardfloat); |
|
} /* reg_cpu_sec() */ |
/configure
1,7 → 1,7
#! /bin/sh |
# From configure.ac Id: configure.ac 1102 2010-07-23 15:35:59Z jeremy using automake version AC_ACVERSION. |
# From configure.ac Id: configure.ac 1103 2010-07-23 19:14:09Z jeremy using automake version AC_ACVERSION. |
# Guess values for system-dependent variables and create Makefiles. |
# Generated by GNU Autoconf 2.63 for or1ksim 2010-07-23. |
# Generated by GNU Autoconf 2.63 for or1ksim 2010-07-30. |
# |
# Report bugs to <openrisc@opencores.org>. |
# |
766,8 → 766,8
# Identity of this package. |
PACKAGE_NAME='or1ksim' |
PACKAGE_TARNAME='or1ksim' |
PACKAGE_VERSION='2010-07-23' |
PACKAGE_STRING='or1ksim 2010-07-23' |
PACKAGE_VERSION='2010-07-30' |
PACKAGE_STRING='or1ksim 2010-07-30' |
PACKAGE_BUGREPORT='openrisc@opencores.org' |
|
# Factoring default headers for most tests. |
1529,7 → 1529,7
# Omit some internal or obsolete options to make the list less imposing. |
# This message is too long to be a string in the A/UX 3.1 sh. |
cat <<_ACEOF |
\`configure' configures or1ksim 2010-07-23 to adapt to many kinds of systems. |
\`configure' configures or1ksim 2010-07-30 to adapt to many kinds of systems. |
|
Usage: $0 [OPTION]... [VAR=VALUE]... |
|
1600,7 → 1600,7
|
if test -n "$ac_init_help"; then |
case $ac_init_help in |
short | recursive ) echo "Configuration of or1ksim 2010-07-23:";; |
short | recursive ) echo "Configuration of or1ksim 2010-07-30:";; |
esac |
cat <<\_ACEOF |
|
1707,7 → 1707,7
test -n "$ac_init_help" && exit $ac_status |
if $ac_init_version; then |
cat <<\_ACEOF |
or1ksim configure 2010-07-23 |
or1ksim configure 2010-07-30 |
generated by GNU Autoconf 2.63 |
|
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, |
1741,7 → 1741,7
This file contains any messages produced by compilers while |
running configure, to aid debugging if configure makes a mistake. |
|
It was created by or1ksim $as_me 2010-07-23, which was |
It was created by or1ksim $as_me 2010-07-30, which was |
generated by GNU Autoconf 2.63. Invocation command line was |
|
$ $0 $@ |
11284,7 → 11284,7
|
# Define the identity of the package. |
PACKAGE='or1ksim' |
VERSION='2010-07-23' |
VERSION='2010-07-30' |
|
|
cat >>confdefs.h <<_ACEOF |
18260,7 → 18260,7
# report actual input values of CONFIG_FILES etc. instead of their |
# values after options handling. |
ac_log=" |
This file was extended by or1ksim $as_me 2010-07-23, which was |
This file was extended by or1ksim $as_me 2010-07-30, which was |
generated by GNU Autoconf 2.63. Invocation command line was |
|
CONFIG_FILES = $CONFIG_FILES |
18323,7 → 18323,7
_ACEOF |
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
ac_cs_version="\\ |
or1ksim config.status 2010-07-23 |
or1ksim config.status 2010-07-30 |
configured by $0, generated by GNU Autoconf 2.63, |
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" |
|
/libtoplevel.c
36,11 → 36,15
#include "or1ksim.h" |
#include "sim-config.h" |
#include "toplevel-support.h" |
#include "debug-unit.h" |
#include "sched.h" |
#include "execute.h" |
#include "pic.h" |
#include "jtag.h" |
#include "spr-defs.h" |
#include "sprs.h" |
|
|
/* Indices of GDB registers that are not GPRs. Must match GDB settings! */ |
#define MAX_GPRS 32 /*!< Maximum GPRs */ |
#define PPC_REGNUM (MAX_GPRS + 0) /*!< Previous PC */ |
235,27 → 239,6
|
|
/*---------------------------------------------------------------------------*/ |
/*!Step the simulator |
|
This is just a wrapper for the run function, specifying a time |
corresponding to a single cycle. This will in fact mean that a single |
instruction is executed, even if takes more than one cycle to execute. |
|
@todo What happens if an event is triggered - that may mean multiple |
instructions. |
|
@return OR1KSIM_RC_OK if we step to completion, OR1KSIM_RC_BRKPT if we hit |
a breakpoint (not clear how this can be set without CLI access) */ |
/*---------------------------------------------------------------------------*/ |
int |
or1ksim_step () |
{ |
return or1ksim_run ((double) config.sim.clkcycle_ps / 1e12); |
|
} /* or1ksim_step () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Reset the run-time simulation end point |
|
Reset the time for which the simulation should run to the specified duration |
535,15 → 518,15
/*---------------------------------------------------------------------------*/ |
/*!Read a block of memory. |
|
@param[in] addr The address to read from. |
@param[out] buf Where to put the data. |
@param[in] addr The address to read from. |
@param[in] len The number of bytes to read. |
|
@return Number of bytes read, or zero if error. */ |
/*---------------------------------------------------------------------------*/ |
int |
or1ksim_read_mem (unsigned char *buf, |
unsigned int addr, |
or1ksim_read_mem (unsigned int addr, |
unsigned char *buf, |
int len) |
{ |
int off; /* Offset into the memory */ |
572,15 → 555,15
/*---------------------------------------------------------------------------*/ |
/*!Write a block of memory. |
|
@param[in] addr The address to write to. |
@param[in] buf Where to get the data from. |
@param[in] addr The address to write to. |
@param[in] len The number of bytes to write. |
|
@return Number of bytes written, or zero if error. */ |
/*---------------------------------------------------------------------------*/ |
int |
or1ksim_write_mem (unsigned char *buf, |
unsigned int addr, |
or1ksim_write_mem (unsigned int addr, |
unsigned char *buf, |
int len) |
{ |
int off; /* Offset into the memory */ |
607,54 → 590,88
|
|
/*---------------------------------------------------------------------------*/ |
/*!Read a single register |
/*!Read a SPR |
|
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC |
(i.e. SPR NPC) and SR (i.e. SPR SR). |
@param[in] sprnum The SPR to read. |
@param[out] sprval_ptr Where to put the data. |
|
@param[out] buf Where to put the data. |
@param[in] regnum The register to read. |
@param[in] len Size of the register in bytes |
|
@return Size of the register, or zero if error. */ |
@return Non-zero (TRUE) on success, zero (FALSE) otherwise. */ |
/*---------------------------------------------------------------------------*/ |
int |
or1ksim_read_reg (unsigned char *buf, |
int regnum, |
int len) |
or1ksim_read_spr (int sprnum, |
unsigned int *sprval_ptr) |
{ |
unsigned long int *regbuf = (unsigned long *) buf; |
|
if (4 != len) |
/* SPR numbers are up to 16 bits long */ |
if ((unsigned int) sprnum <= 0xffff) |
{ |
return 0; /* Not 32-bit reg */ |
*sprval_ptr = (unsigned int) mfspr ((uint16_t) sprnum); |
return 1; |
} |
|
/* Get the relevant register */ |
if (regnum < MAX_GPRS) |
else |
{ |
*regbuf = cpu_state.reg[regnum]; |
return 0; /* Silent failure */ |
} |
else if (PPC_REGNUM == regnum) |
} /* or1skim_read_spr () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Write a SPR |
|
@param[in] sprnum The SPR to write. |
@param[in] sprval The data to write. |
|
@return Non-zero (TRUE) on success, zero (FALSE) otherwise. */ |
/*---------------------------------------------------------------------------*/ |
int |
or1ksim_write_spr (int sprnum, |
unsigned int sprval) |
{ |
/* SPR numbers are up to 16 bits long */ |
if ((unsigned int) sprnum <= 0xffff) |
{ |
*regbuf = cpu_state.sprs[SPR_PPC]; |
mtspr ((uint16_t) sprnum, sprval); |
return 1; |
} |
else if (NPC_REGNUM == regnum) |
else |
{ |
*regbuf = cpu_state.pc; |
return 0; /* Silent failure */ |
} |
else if (SR_REGNUM == regnum) |
} /* or1ksim_write_spr () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Read a single register |
|
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC |
(i.e. SPR NPC) and SR (i.e. SPR SR). |
|
Map to the corresponding SPR. |
|
@param[in] regnum The register to read. |
@param[out] regval_ptr Where to put the data. |
|
@return Non-zero (TRUE) on success, zero (FALSE) otherwise. */ |
/*---------------------------------------------------------------------------*/ |
int |
or1ksim_read_reg (int regnum, |
unsigned int *regval_ptr) |
{ |
/* GPR's */ |
if (regnum < MAX_GPRS) |
{ |
*regbuf = cpu_state.sprs[SPR_SR]; |
return or1ksim_read_spr (regnum + SPR_GPR_BASE, regval_ptr); |
} |
else |
|
/* SPR's or unknown */ |
switch (regnum) |
{ |
case PPC_REGNUM: return or1ksim_read_spr (SPR_PPC, regval_ptr); |
case NPC_REGNUM: return or1ksim_read_spr (SPR_NPC, regval_ptr); |
case SR_REGNUM: return or1ksim_read_spr (SPR_SR, regval_ptr); |
default: |
/* Silent error response if we don't know the register */ |
return 0; |
} |
|
return len; |
|
} /* or1ksim_read_reg () */ |
|
|
662,60 → 679,46
/*!Write a single register |
|
The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC |
(i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a |
sequence of bytes in target endian order. |
(i.e. SPR NPC) and SR (i.e. SPR SR). |
|
Each byte is packed as a pair of hex digits. |
Map to the corresponding SPR |
|
@param[in] buf Where to get the data from. |
@param[in] regval The register to write. |
@param[in] regnum The register to write. |
@param[in] len Size of the register in bytes |
|
@return Size of the register, or zero if error. */ |
@return Non-zero (TRUE) on success, zero (FALSE) otherwise. */ |
/*---------------------------------------------------------------------------*/ |
int |
or1ksim_write_reg (unsigned char *buf, |
int regnum, |
int len) |
or1ksim_write_reg (int regnum, |
unsigned int regval) |
{ |
unsigned long int *regbuf = (unsigned long *) buf; |
unsigned long int regval = *regbuf; |
|
if (4 != len) |
/* GPR's */ |
if (regnum < MAX_GPRS) |
{ |
return 0; /* Not 32-bit reg */ |
return or1ksim_write_spr (regnum + SPR_GPR_BASE, regval); |
} |
|
/* Set the relevant register */ |
if (regnum < MAX_GPRS) |
/* SPR's or unknown */ |
switch (regnum) |
{ |
cpu_state.reg[regnum] =regval; |
} |
else if (PPC_REGNUM == regnum) |
{ |
cpu_state.sprs[SPR_PPC] = regval; |
} |
else if (NPC_REGNUM == regnum) |
{ |
if (cpu_state.pc != regval) |
{ |
cpu_state.pc = regval; |
cpu_state.delay_insn = 0; |
pcnext = regval + 4; |
} |
} |
else if (SR_REGNUM == regnum) |
{ |
cpu_state.sprs[SPR_SR] = regval; |
} |
else |
{ |
case PPC_REGNUM: return or1ksim_write_spr (SPR_PPC, regval); |
case NPC_REGNUM: return or1ksim_write_spr (SPR_NPC, regval); |
case SR_REGNUM: return or1ksim_write_spr (SPR_SR, regval); |
default: |
/* Silent error response if we don't know the register */ |
return 0; |
} |
} /* or1ksim_write_reg () */ |
|
return len; |
|
/*---------------------------------------------------------------------------*/ |
/*!Set the simulator stall state. |
|
} /* or1ksim_write_reg () */ |
@param[in] state The stall state to set. */ |
/*---------------------------------------------------------------------------*/ |
void |
or1ksim_set_stall_state (int state) |
{ |
set_stall_state (state ? 1 : 0); |
|
|
} /* or1ksim_set_stall_state () */ |
/pic/pic.c
178,7 → 178,7
{ |
struct config_section *sec = reg_config_sec ("pic", NULL, NULL); |
|
reg_config_param (sec, "enabled", paramt_int, pic_enabled); |
reg_config_param (sec, "edge_trigger", paramt_int, pic_edge_trigger); |
reg_config_param (sec, "enabled", PARAMT_INT, pic_enabled); |
reg_config_param (sec, "edge_trigger", PARAMT_INT, pic_edge_trigger); |
|
} /* reg_pic_sec() */ |
/pm/pm.c
84,6 → 84,6
{ |
struct config_section *sec = reg_config_sec ("pm", NULL, NULL); |
|
reg_config_param (sec, "enabled", paramt_int, pm_enabled); |
reg_config_param (sec, "enabled", PARAMT_INT, pm_enabled); |
|
} /* reg_pm_sec() */ |
/sim-config.c
66,19 → 66,184
#include "argtable2.h" |
|
|
/*! A structure used to represent possible parameters in a section. */ |
struct config_param |
{ |
char *name; /* param name */ |
enum param_t type; /* param type */ |
void (*func) (union param_val val, /* Setter function */ |
void *dat); |
struct config_param *next; /* Next param in list */ |
|
}; /* struct config_param */ |
|
|
/*! Config file line count */ |
static int line_number; |
|
/*! The global configuration data structure */ |
struct config config; |
|
/*! The global runtime status data structure */ |
struct runtime runtime; |
|
struct config_section *cur_section; |
/*! Master list of sections it is possible to configure. */ |
static struct config_section *section_master_list = NULL; |
|
struct config_section *sections = NULL; |
|
/* Forward declarations */ |
static void read_script_file (const char *filename); |
/* -------------------------------------------------------------------------- */ |
/*!Register a parameter for a section |
|
Add a new parameter to the list of parameters that may be set for a given |
section. |
|
@param[in] sec The section containing the parameter. |
@param[in] param Name of the parameter |
@param[in] type Type of the parameter |
@param[in] param_cb Call back function to set this parameter. */ |
/* -------------------------------------------------------------------------- */ |
void |
reg_config_param (struct config_section *sec, |
const char *param, |
enum param_t type, |
void (*param_cb) (union param_val, |
void *)) |
{ |
struct config_param *new = malloc (sizeof (struct config_param)); |
|
/*---------------------------------------------------------------------------*/ |
if (!new) |
{ |
fprintf (stderr, "ERROR: Out-of-memory allocating parameter: exiting,\n"); |
exit (1); |
} |
|
if (!(new->name = strdup (param))) |
{ |
fprintf (stderr, "ERROR: Out-of-memory allocating parameter name: " |
"exiting,\n"); |
exit (1); |
} |
|
/* Set up the parameter */ |
new->func = param_cb; |
new->type = type; |
|
/* Insert on head of list */ |
new->next = sec->params; |
sec->params = new; |
|
} /* reg_config_param () */ |
|
|
/* -------------------------------------------------------------------------- */ |
/*!Register a new section. |
|
Add a new section to the list of sections that may be found in a config |
file. |
|
@param[in] section The name of the new section. |
@param[in] sec_start Function to call at start of section configuration |
(or NULL if none) |
@param[in] sec_end Function to call at end of section configuration |
(or NULL if none). Returns pointer to an arbitrary |
data structure. |
|
@return A pointer to the section data structure for the new section. */ |
/* -------------------------------------------------------------------------- */ |
struct config_section * |
reg_config_sec (const char *section, |
void *(*sec_start) (void), |
void (*sec_end) (void *)) |
{ |
struct config_section *new = malloc (sizeof (struct config_section)); |
|
if (!new) |
{ |
fprintf (stderr, "ERROR: Out-of-memory allocating section: exiting,\n"); |
exit (1); |
} |
|
if (!(new->name = strdup (section))) |
{ |
fprintf (stderr, "ERROR: Out-of-memory allocating section name: " |
"exiting,\n"); |
exit (1); |
} |
|
/* Set up the section */ |
new->next = section_master_list; |
new->sec_start = sec_start; |
new->sec_end = sec_end; |
new->params = NULL; |
|
/* Insert the section */ |
section_master_list = new; |
|
return new; |
|
} /* reg_config_sec () */ |
|
|
/* -------------------------------------------------------------------------- */ |
/*!Look up a section |
|
Given a section name, return the data structure describing that section. |
|
@param[in] name The section to look for. |
|
@return A pointer to the section config data structure, or NULL if the |
section is not found */ |
/* -------------------------------------------------------------------------- */ |
static struct config_section * |
lookup_section (char *name) |
{ |
struct config_section *cur = NULL; |
|
for (cur = section_master_list; NULL != cur; cur = cur->next) |
{ |
if (strcmp (cur->name, name) == 0) |
{ |
break; |
} |
} |
|
return cur; |
|
} /* lookup_section () */ |
|
|
/* -------------------------------------------------------------------------- */ |
/*!Look up a parameter for a section |
|
Given a parameter name and a section data structure, return the data |
structure describing that parameter |
|
@param[in] name The parameter to look for. |
@param[in] sec The section containing the parameter. |
|
@return A pointer to the parameter config data structure, or NULL if the |
parameter is not found */ |
/* -------------------------------------------------------------------------- */ |
static struct config_param * |
lookup_param (char *name, |
struct config_section *sec) |
{ |
struct config_param *param = NULL; |
|
for (param = sec->params; NULL != param; param = param->next) |
{ |
if (strcmp (param->name, name) == 0) |
{ |
break; |
} |
} |
|
return param; |
|
} /* lookup_param () */ |
|
|
/* -------------------------------------------------------------------------- */ |
/*!Set default configuration parameters for fixed components |
|
These values are held in the global config variable. Parameter orders |
85,8 → 250,8
match the order in the corresponding section registration function and |
documentation. |
|
Also set some starting values for runtime elements. */ |
/*---------------------------------------------------------------------------*/ |
Also set some starting values for runtime elements. */ |
/* -------------------------------------------------------------------------- */ |
void |
init_defconfig () |
{ |
262,7 → 427,496
} /* init_defconfig() */ |
|
|
/* -------------------------------------------------------------------------- */ |
/*!Set a configuration parameter. |
|
We have a string representing the value, and a data structure representing |
the particular parameter. Break out the value and call the setter function |
to set its value in the section. |
|
The value text is guaranteed to have no leading or trailing whitespace. |
|
@param[in] cur_section Spec of the section currently being configured. |
@param[in] param Spec of the parameter we are setting. |
@param[in] val_text The parameter value text */ |
/* -------------------------------------------------------------------------- */ |
static void |
set_config_param (struct config_section *cur_section, |
struct config_param *param, |
char *val_text) |
{ |
union param_val val; |
|
/* Break out the different parameter types */ |
switch (param->type) |
{ |
case PARAMT_NONE: |
break; |
|
case PARAMT_INT: |
val.int_val = strtol (val_text, NULL, 0); |
break; |
|
case PARAMT_LONGLONG: |
val.longlong_val = strtoll (val_text, NULL, 0); |
break; |
|
case PARAMT_ADDR: |
val.addr_val = strtoul (val_text, NULL, 0); |
break; |
|
case PARAMT_WORD: |
case PARAMT_STR: |
/* Word and string are the same thing by now. */ |
val.str_val = val_text; |
break; |
} |
|
/* Call the setter function */ |
param->func (val, cur_section->dat); |
|
} /* set_config_param () */ |
|
|
/* -------------------------------------------------------------------------- */ |
/*!Scan the next word, skipping any preceding space. |
|
A word is anything that is not white space, except where the white space is |
within quotation marks. Return the number of newlines we have to skip. |
|
@param[in] f The file handle to read from |
@param[in] word A buffer in which to store the word. |
|
@return The text of the next entity or NULL at end of file. Note strings |
have their quotation marks removed. */ |
/* -------------------------------------------------------------------------- */ |
static char * |
next_word (FILE *f, |
char word[]) |
{ |
int c; |
int i; |
|
/* Skip the whitespace */ |
do |
{ |
c = fgetc (f); |
|
line_number += ('\n' == c) ? 1: 0; |
} |
while ((EOF != c) && isspace (c)); |
|
/* Get the word> Special treatment if it is a string. */ |
if ('"' == c) |
{ |
/* We have a string. Skip the opening quote. */ |
c = fgetc (f); |
|
for (i = 0; i < (STR_SIZE - 1); i++) |
{ |
if ('"' == c) |
{ |
c = fgetc (f); /* So ungetc works */ |
break; /* End of the string */ |
} |
else if ('\n' == c) |
{ |
line_number++; |
} |
else if (EOF == c) |
{ |
fprintf (stderr, "ERROR: EOF in middle of string: exiting.\n"); |
exit (1); |
} |
|
word[i] = c; |
c = fgetc (f); |
} |
|
/* Skip the closing quote */ |
c = fgetc (f); |
} |
else |
{ |
/* We have a space delimited word */ |
for (i = 0; i < (STR_SIZE - 1); i++) |
{ |
if ((EOF == c) || isspace (c)) |
{ |
break; /* End of the word */ |
} |
|
word[i] = c; |
c = fgetc (f); |
} |
} |
|
word[i] = '\0'; /* Terminate the word */ |
|
if ((STR_SIZE - 1) == i) |
{ |
word[10]= '\0'; |
fprintf (stderr, |
"ERROR: Symbol beginning %s on line %d too long: exiting.\n", |
word, line_number); |
exit (1); |
} |
|
ungetc (c, f); /* Ready for next time */ |
|
return (0 == i) ? NULL : word; |
|
} /* next_word () */ |
|
|
/* -------------------------------------------------------------------------- */ |
/*!Read the next lexeme from the a config file. |
|
At this stage we are just breaking things out into space delimited |
entities, stripping out comments. |
|
@param[in] f The file handle to read from |
@param[in] lexeme A buffer in which to store the lexeme. |
|
@return The text of the next entity or NULL at end of file. */ |
/* -------------------------------------------------------------------------- */ |
static char * |
next_lexeme (FILE *f, |
char lexeme[]) |
{ |
if (NULL == next_word (f, lexeme)) |
{ |
return NULL; |
} |
|
/* Skip any comments */ |
while (0 ==strncmp (lexeme, "/*", 2)) |
{ |
/* Look for the closing '*' and '/'. */ |
char c0 = '\0'; |
char c1 = '\0'; |
|
while (('*' != c0) || ('/' != c1)) |
{ |
c0 = c1; |
c1 = fgetc (f); |
|
line_number += ('\n' == c1) ? 1 : 0; |
|
/* We assume if we hit EOF we have a serious problem and die. */ |
if (feof (f)) |
{ |
fprintf (stderr, "ERROR: Comment reached EOF.\n"); |
exit (1); |
} |
} |
|
/* Get the next lexeme */ |
if (NULL == next_word (f, lexeme)) |
{ |
return NULL; |
} |
} |
|
return lexeme; |
|
} /* next_lexeme () */ |
|
|
/* -------------------------------------------------------------------------- */ |
/*!Read configuration from a script file. |
|
The syntax of script file is: |
|
[section x |
[param [=] value]+ |
end]* |
|
Example: |
|
section mc |
enabled = 1 |
POC = 0x47892344 |
end |
|
The config file is searched for first in the local directory, then in |
${HOME}/.or1ksim, then (for backwards compatibility) in ${HOME}/.or1ksim. |
|
If the file is not found, then a rude message is printed. The system will |
just use default values. |
|
@param[in] filename The configuration file to use. */ |
/* -------------------------------------------------------------------------- */ |
static void |
read_script_file (const char *filename) |
{ |
FILE *f; |
char *home = getenv ("HOME"); |
char ctmp1[STR_SIZE]; |
char ctmp2[STR_SIZE]; |
char *dir; |
|
/* Attempt to open the config file. If we fail, give up with a rude |
message. */ |
sprintf (ctmp1, "%s/.or1ksim/%s", home, filename); |
sprintf (ctmp2, "%s/.or1k/%s", home, filename); |
|
if (NULL != (f = fopen (filename, "r"))) |
{ |
dir = "."; |
} |
else if (home && (NULL != (f = fopen (ctmp1, "r")))) |
{ |
dir = ctmp1; |
} |
else if (home && (NULL != (f = fopen (ctmp2, "r")))) |
{ |
dir = ctmp2; |
} |
else |
{ |
fprintf (stderr, "Warning: Failed to open script file \"%s\". Ignored.\n", |
filename); |
return; |
} |
|
/* Log the config file we have just opened if required. */ |
if (config.sim.verbose) |
{ |
PRINTF ("Reading script file from \"%s/%s\"...\n", dir, filename); |
} |
|
/* Process the config file. */ |
char lexeme[STR_SIZE]; /* Next entity from the input */ |
int in_section_p = 0; /* Are we processing a section */ |
|
struct config_section *cur_section = NULL; /* Section being processed */ |
|
line_number = 1; |
|
while (NULL != next_lexeme (f, lexeme)) |
{ |
/* Get the next symbol. Four possibilities. |
|
1. It's "section". Only if we are not currently in a section. Process |
the start of a section. |
|
2. It's "end". Only if we are currently in a section. Process the end |
of a section. |
|
3. Anything else while we are in a section. Assume it is a parameter |
for the current section. |
|
4. Anything else. An error. |
*/ |
if (!in_section_p && (0 == strcmp (lexeme, "section"))) |
{ |
/* We have the start of a section */ |
if (NULL == next_lexeme (f, lexeme)) |
{ |
fprintf (stderr, "ERROR: %s/%s: Section name required at line " |
"%d. Exiting\n", dir, filename, line_number); |
exit (1); |
} |
|
cur_section = lookup_section (lexeme); |
|
if (NULL != cur_section) |
{ |
/* Valid section, run its startup code, with any data saved. */ |
cur_section->dat = NULL; |
|
if (cur_section->sec_start) |
{ |
cur_section->dat = cur_section->sec_start (); |
} |
|
in_section_p = 1; /* Now in a section */ |
} |
else |
{ |
/* Skip an unrecognized section with a warning. */ |
fprintf (stderr, "Warning: %s/%s: Unrecognized section: %s at " |
"line %d: ignoring.\n", dir, filename, lexeme, |
line_number); |
|
/* just skip section */ |
while (NULL != next_lexeme (f, lexeme)) |
{ |
if (strcmp (lexeme, "end")) |
{ |
break; |
} |
} |
} |
} |
else if (in_section_p && strcmp (lexeme, "end") == 0) |
{ |
/* End of section. Run the end of section code */ |
if (cur_section->sec_end) |
{ |
cur_section->sec_end (cur_section->dat); |
} |
|
in_section_p = 0; /* Not in a section any more */ |
} |
else if (in_section_p) |
{ |
/* We're in a section, so this must be a parameter. */ |
struct config_param *param; |
char *param_val; |
|
param = lookup_param (lexeme, cur_section); |
|
/* If we didn't recognize, then warn and skip to end of line/file) */ |
if (NULL == param) |
{ |
fprintf (stderr, "Warning: %s/%s: Unrecognized parameter: %s at " |
"line %d; ignored.\n", dir, filename, lexeme, |
line_number); |
|
/* Skip to end of line */ |
while (( '\n' != fgetc (f)) || feof (f)) |
; |
|
line_number++; |
continue; /* Start looking again */ |
} |
|
/* Get the argument if one is expected. */ |
if (PARAMT_NONE != param->type) |
{ |
param_val = next_lexeme (f, lexeme); |
|
if (NULL == param_val) |
{ |
fprintf (stderr, "Warning: %s/%s: No argument to parameter " |
"%s at line %d; ignored.\n", dir, filename, |
param->name, line_number); |
|
/* Skip to end of line */ |
while (( '\n' != fgetc (f)) || feof (f)) |
; |
|
line_number++; |
continue; /* Start looking again */ |
} |
|
/* We allow an optional '=' */ |
if (0 == strcmp (lexeme, "=")) |
{ |
param_val = next_lexeme (f, lexeme); |
|
if (NULL == param_val) |
{ |
fprintf (stderr, "Warning: %s/%s: No argument to " |
"parameter %s at line %d; ignored.\n", dir, |
filename, param->name, line_number); |
|
/* Skip to end of line */ |
while (( '\n' != fgetc (f)) || feof (f)) |
; |
|
line_number++; |
continue; /* Start looking again */ |
} |
} |
} |
else |
{ |
/* No argument */ |
param_val = NULL; |
} |
|
/* Apply the parameter */ |
set_config_param (cur_section, param, param_val); |
} |
else |
{ |
/* We're not in a section, so we don't know what we have */ |
fprintf (stderr, "Warning: %s/%s: Unrecognized config file contents " |
" at line %d: ignored.\n", dir, filename, line_number); |
|
/* Skip to end of line */ |
while (( '\n' != fgetc (f)) || feof (f)) |
; |
|
line_number++; |
continue; /* Start looking again */ |
} |
} |
|
fclose (f); /* All done */ |
|
} /* read_script_file () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Allocate a memory block |
|
We can request a block of memory be allocated from the command line, rather |
than in a configuration file. It will be allocated, starting at address |
zero. |
|
The memory size may be presented in any format recognized by strtol, |
optionally followed by "G" or "g", "M" or "m" or "K" or "k" for giga, mega |
and kilo bytes respectively, and leading to mutliplcation by 2^30, 2^20 and |
2^10 respectively. |
|
This is intended for simple use of the simulator in tool chain |
verification, where the detailed memory behavior does not matter. |
|
@param[in] size Memory size. */ |
/*---------------------------------------------------------------------------*/ |
static void |
alloc_memory_block (const char *size) |
{ |
/* Sort out the memory size. */ |
unsigned long int multiplier; |
int last_ch = strlen (size) - 1; |
|
switch (size[last_ch]) |
{ |
case 'G': case 'g': multiplier = 0x40000000UL; break; |
case 'M': case 'm': multiplier = 0x100000UL; break; |
case 'K': case 'k': multiplier = 0x400UL; break; |
default: multiplier = 0x1UL; break; |
} |
unsigned long int mem_size = strtoul (size, NULL, 0) * multiplier; |
|
if (0 == mem_size) |
{ |
fprintf (stderr, "Warning: Memory size %s not recognized: ignored.\n", |
size); |
return; |
} |
|
if (mem_size > 0xffffffff) |
{ |
fprintf (stderr, "Warning: Memory size %s too large: ignored.\n", |
size); |
return; |
} |
|
/* Turn the memory size back into a decimal string and allocate it */ |
char str_size[11]; |
sprintf (str_size, "%lu\n", mem_size); |
|
struct config_section *sec = lookup_section ("memory"); |
|
sec->dat = sec->sec_start (); |
|
set_config_param (sec, lookup_param ("name", sec), "Default RAM"); |
set_config_param (sec, lookup_param ("type", sec), "unknown"); |
set_config_param (sec, lookup_param ("baseaddr", sec), "0"); |
set_config_param (sec, lookup_param ("size", sec), str_size); |
|
sec->sec_end (sec->dat); |
|
} /* alloc_memory_block () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*! Parse the arguments for the standalone simulator |
|
Updated by Jeremy Bennett to use argtable2. |
275,24 → 929,23
int |
parse_args (int argc, char *argv[]) |
{ |
struct arg_lit *vercop; |
struct arg_lit *help; |
struct arg_lit *vercop; |
struct arg_lit *help; |
struct arg_file *cfg_file; |
struct arg_lit *nosrv; |
struct arg_int *srv; |
struct arg_str *dbg; |
struct arg_lit *command; |
struct arg_lit *quiet; |
struct arg_lit *report_mem_errs; |
struct arg_lit *strict_npc; |
struct arg_lit *profile; |
struct arg_lit *mprofile; |
struct arg_lit *nosrv; |
struct arg_int *srv; |
struct arg_str *mem; |
struct arg_str *dbg; |
struct arg_lit *command; |
struct arg_lit *quiet; |
struct arg_lit *verbose; |
struct arg_lit *report_mem_errs; |
struct arg_lit *strict_npc; |
struct arg_lit *profile; |
struct arg_lit *mprofile; |
struct arg_file *load_file; |
struct arg_end *end; |
struct arg_end *end; |
|
void *argtab[14]; |
int nerrors; |
|
/* Specify each argument, with fall back values */ |
vercop = arg_lit0 ("v", "version", "version and copyright notice"); |
help = arg_lit0 ("h", "help", "print this help message"); |
303,9 → 956,11
srv = arg_int0 (NULL, "srv", "<n>", "port number (default random)"); |
srv->ival[0] = rand () % (65536 - 49152) + 49152; |
srv->hdr.flag |= ARG_HASOPTVALUE; |
mem = arg_str0 ("m", "memory", "<n>", "add memory block of <n> bytes"); |
dbg = arg_str0 ("d", "debug-config", "<str>", "Debug config string"); |
command = arg_lit0 ("i", "interactive", "launch interactive prompt"); |
quiet = arg_lit0 ("q", "quiet", "minimal message output"); |
verbose = arg_lit0 ("V", "verbose", "verbose message output"); |
report_mem_errs = arg_lit0 (NULL, "report-memory-errors", |
"Report out of memory accesses"); |
strict_npc = arg_lit0 (NULL, "strict-npc", "setting NPC flushes pipeline"); |
314,24 → 969,27
load_file = arg_file0 (NULL, NULL, "<file>", "OR32 executable"); |
end = arg_end (20); |
|
/* Set up the argument table */ |
argtab[ 0] = vercop; |
argtab[ 1] = help; |
argtab[ 2] = cfg_file; |
argtab[ 3] = nosrv; |
argtab[ 4] = srv; |
argtab[ 5] = dbg; |
argtab[ 6] = command; |
argtab[ 7] = quiet; |
argtab[ 8] = report_mem_errs; |
argtab[ 9] = strict_npc; |
argtab[10] = profile; |
argtab[11] = mprofile; |
argtab[12] = load_file; |
argtab[13] = end; |
/* The argument table */ |
void *argtab[] = { |
vercop, |
help, |
cfg_file, |
nosrv, |
srv, |
mem, |
dbg, |
command, |
quiet, |
verbose, |
report_mem_errs, |
strict_npc, |
profile, |
mprofile, |
load_file, |
end }; |
|
/* Parse */ |
nerrors = arg_parse (argc, argv, argtab); |
int nerrors = arg_parse (argc, argv, argtab); |
|
/* Special case here is if help or version is specified, we ignore any other |
errors and just print the help or version information and then give up. */ |
365,16 → 1023,44
return 1; |
} |
|
/* Process config file next, so any other command args will override */ |
/* Request for quiet running */ |
config.sim.quiet = quiet->count; |
|
/* Request for verbose running. Not sensible to use with quiet as well. */ |
if (quiet->count && verbose->count) |
{ |
fprintf (stderr, "Warning: Cannot specify both --verbose and --quiet: " |
"--vervose ignored.\n"); |
config.sim.verbose = 0; |
} |
else |
{ |
config.sim.verbose = verbose->count; |
} |
|
/* Request for memory errors */ |
config.sim.report_mem_errs = report_mem_errs->count; |
|
/* Process config file next (if given), so any other command args will |
override */ |
if (0 == cfg_file->count) |
{ |
fprintf (stderr, |
"Warning: No config file given, default configuration used\n"); |
if (config.sim.verbose) |
{ |
fprintf (stderr, "Default configuration used\n"); |
} |
} |
else |
{ |
read_script_file (cfg_file->filename[0]); |
} |
|
read_script_file (cfg_file->filename[0]); |
/* Allocate a memory block */ |
if (mem->count > 0) |
{ |
alloc_memory_block (mem->sval[0]); |
} |
|
|
/* Remote debug server */ |
if (nosrv->count > 0) |
{ |
407,12 → 1093,6
/* Interactive operation */ |
runtime.sim.iprompt = command->count; |
|
/* Request for quiet running */ |
config.sim.quiet = quiet->count; |
|
/* Request for quiet running */ |
config.sim.report_mem_errs = report_mem_errs->count; |
|
/* Request for strict NPC behavior (flush the pipeline on change) */ |
config.sim.strict_npc = strict_npc->count; |
|
477,31 → 1157,25
} |
} |
|
struct config_param |
{ |
char *name; |
enum param_t type; |
void (*func) (union param_val, void *dat); |
struct config_param *next; |
}; |
/* Simulator configuration */ |
|
void |
base_include (union param_val val, void *dat) |
{ |
read_script_file (val.str_val); |
cur_section = NULL; |
} |
|
/*---------------------------------------------[ Simulator configuration ]---*/ |
/*---------------------------------------------------------------------------*/ |
/*!Turn on verbose messages. |
|
|
void |
sim_verbose (union param_val val, void *dat) |
@param[in] val Non-zero (TRUE) to turn on verbose messages, zero (FALSE) |
otherwise. |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_verbose (union param_val val, |
void *dat) |
{ |
config.sim.verbose = val.int_val; |
} |
|
} /* sim_verbose () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Set the simulator debug message level |
|
511,7 → 1185,7
@param[in] val The value to use |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
void |
static void |
sim_debug (union param_val val, |
void *dat) |
{ |
534,14 → 1208,30
} /* sim_debug() */ |
|
|
void |
sim_profile (union param_val val, void *dat) |
/*---------------------------------------------------------------------------*/ |
/*!Turn on profiling |
|
@param[in] val Non-zero (TRUE) to turn on profiling, zero (FALSE) otherwise. |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_profile (union param_val val, |
void *dat) |
{ |
config.sim.profile = val.int_val; |
} |
|
void |
sim_prof_fn (union param_val val, void *dat) |
} /* sim_profile () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Specify the profiling file name. |
|
@param[in] val The profiling file name |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_prof_fn (union param_val val, |
void *dat) |
{ |
if (NULL != config.sim.prof_fn) |
{ |
549,15 → 1239,33
} |
|
config.sim.prof_fn = strdup(val.str_val); |
} |
|
void |
sim_mprofile (union param_val val, void *dat) |
} /* sim_prof_fn () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Turn on memory profiling |
|
@param[in] val Non-zero (TRUE) to turn on memory profiling, zero (FALSE) |
otherwise. |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_mprofile (union param_val val, |
void *dat) |
{ |
config.sim.mprofile = val.int_val; |
} |
|
void |
} /* sim_mprofile () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Specify the memory profiling file name. |
|
@param[in] val The memory profiling file name |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_mprof_fn (union param_val val, void *dat) |
{ |
if (NULL != config.sim.mprof_fn) |
566,20 → 1274,38
} |
|
config.sim.mprof_fn = strdup (val.str_val); |
} |
|
void |
sim_history (union param_val val, void *dat) |
} /* sim_mprof_fn () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Turn on execution tracking. |
|
@param[in] val Non-zero (TRUE) to turn on tracking, zero (FALSE) otherwise. |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_history (union param_val val, |
void *dat) |
{ |
config.sim.history = val.int_val; |
} |
|
void |
sim_exe_log (union param_val val, void *dat) |
|
/*---------------------------------------------------------------------------*/ |
/*!Record an execution log |
|
@param[in] val Non-zero (TRUE) to turn on logging, zero (FALSE) otherwise. |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_exe_log (union param_val val, |
void *dat) |
{ |
config.sim.exe_log = val.int_val; |
} |
|
} /* sim_exe_log () */ |
|
/*---------------------------------------------------------------------------*/ |
/*!Set the execution log type |
|
589,7 → 1315,7
@param[in] val The value to use |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
void |
static void |
sim_exe_log_type (union param_val val, |
void *dat) |
{ |
617,25 → 1343,64
} /* sim_exe_log_type() */ |
|
|
void |
sim_exe_log_start (union param_val val, void *dat) |
/*---------------------------------------------------------------------------*/ |
/*!Set the execution log start address |
|
Address at which to start logging. |
|
@param[in] val The value to use |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_exe_log_start (union param_val val, |
void *dat) |
{ |
config.sim.exe_log_start = val.longlong_val; |
} |
|
void |
sim_exe_log_end (union param_val val, void *dat) |
} /* sim_exe_log_start () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Set the execution log end address |
|
Address at which to end logging. |
|
@param[in] val The value to use |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_exe_log_end (union param_val val, |
void *dat) |
{ |
config.sim.exe_log_end = val.longlong_val; |
} |
|
void |
sim_exe_log_marker (union param_val val, void *dat) |
} /* sim_exe_log_end () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Specify number of instruction between printing horizontal markers |
|
Control of log format |
|
@param[in] val The value to use |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_exe_log_marker (union param_val val, |
void *dat) |
{ |
config.sim.exe_log_marker = val.int_val; |
} |
|
void |
} /* sim_exe_log_marker () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Specify the execution log file name. |
|
@param[in] val The execution log file name |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_exe_log_fn (union param_val val, void *dat) |
{ |
if (NULL != config.sim.exe_log_fn) |
644,15 → 1409,31
} |
|
config.sim.exe_log_fn = strdup (val.str_val); |
} |
|
void |
} /* sim_exe_log_fn () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Turn on binary instruction logging |
|
@param[in] val Non-zero (TRUE) to turn on logging, zero (FALSE) otherwise. |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_exe_bin_insn_log (union param_val val, void *dat) |
{ |
config.sim.exe_bin_insn_log = val.int_val; |
} |
|
void |
} /* sim_exe_bin_insn_log () */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Specify the binary instruction log file name. |
|
@param[in] val The binary instruction log file name |
@param[in] dat The config data structure (not used here) */ |
/*---------------------------------------------------------------------------*/ |
static void |
sim_exe_bin_insn_log_fn (union param_val val, void *dat) |
{ |
if (NULL != config.sim.exe_bin_insn_log_fn) |
661,12 → 1442,10
} |
|
config.sim.exe_bin_insn_log_fn = strdup (val.str_val); |
} |
|
} /* sim_exe_bin_insn_log_fn () */ |
|
|
|
|
/*---------------------------------------------------------------------------*/ |
/*!Set the clock cycle time. |
|
742,36 → 1521,44
{ |
struct config_section *sec = reg_config_sec ("sim", NULL, NULL); |
|
reg_config_param (sec, "verbose", paramt_int, sim_verbose); |
reg_config_param (sec, "debug", paramt_int, sim_debug); |
reg_config_param (sec, "profile", paramt_int, sim_profile); |
reg_config_param (sec, "prof_file", paramt_str, sim_prof_fn); |
reg_config_param (sec, "prof_fn", paramt_str, sim_prof_fn); |
reg_config_param (sec, "mprofile", paramt_int, sim_mprofile); |
reg_config_param (sec, "mprof_file", paramt_str, sim_mprof_fn); |
reg_config_param (sec, "mprof_fn", paramt_str, sim_mprof_fn); |
reg_config_param (sec, "history", paramt_int, sim_history); |
reg_config_param (sec, "exe_log", paramt_int, sim_exe_log); |
reg_config_param (sec, "exe_log_type", paramt_word, sim_exe_log_type); |
reg_config_param (sec, "exe_log_start", paramt_longlong, sim_exe_log_start); |
reg_config_param (sec, "exe_log_end", paramt_longlong, sim_exe_log_end); |
reg_config_param (sec, "exe_log_marker", paramt_int, sim_exe_log_marker); |
reg_config_param (sec, "exe_log_file", paramt_str, sim_exe_log_fn); |
reg_config_param (sec, "exe_log_fn", paramt_str, sim_exe_log_fn); |
reg_config_param (sec, "exe_bin_insn_log",paramt_int, sim_exe_bin_insn_log); |
reg_config_param (sec, "exe_bin_insn_log_fn",paramt_str, sim_exe_bin_insn_log_fn); |
reg_config_param (sec, "exe_bin_insn_log_file",paramt_str, sim_exe_bin_insn_log_fn); |
reg_config_param (sec, "clkcycle", paramt_word, sim_clkcycle); |
reg_config_param (sec, "verbose", PARAMT_INT, sim_verbose); |
reg_config_param (sec, "debug", PARAMT_INT, sim_debug); |
reg_config_param (sec, "profile", PARAMT_INT, sim_profile); |
reg_config_param (sec, "prof_file", PARAMT_STR, sim_prof_fn); |
reg_config_param (sec, "prof_fn", PARAMT_STR, sim_prof_fn); |
reg_config_param (sec, "mprofile", PARAMT_INT, sim_mprofile); |
reg_config_param (sec, "mprof_file", PARAMT_STR, sim_mprof_fn); |
reg_config_param (sec, "mprof_fn", PARAMT_STR, sim_mprof_fn); |
reg_config_param (sec, "history", PARAMT_INT, sim_history); |
reg_config_param (sec, "exe_log", PARAMT_INT, sim_exe_log); |
reg_config_param (sec, "exe_log_type", PARAMT_WORD, sim_exe_log_type); |
reg_config_param (sec, "exe_log_start", PARAMT_LONGLONG, sim_exe_log_start); |
reg_config_param (sec, "exe_log_end", PARAMT_LONGLONG, sim_exe_log_end); |
reg_config_param (sec, "exe_log_marker", PARAMT_INT, sim_exe_log_marker); |
reg_config_param (sec, "exe_log_file", PARAMT_STR, sim_exe_log_fn); |
reg_config_param (sec, "exe_log_fn", PARAMT_STR, sim_exe_log_fn); |
|
reg_config_param (sec, "exe_bin_insn_log", PARAMT_INT, |
sim_exe_bin_insn_log); |
reg_config_param (sec, "exe_bin_insn_log_fn", PARAMT_STR, |
sim_exe_bin_insn_log_fn); |
reg_config_param (sec, "exe_bin_insn_log_file", PARAMT_STR, |
sim_exe_bin_insn_log_fn); |
|
reg_config_param (sec, "clkcycle", PARAMT_WORD, sim_clkcycle); |
|
} /* reg_sim_sec() */ |
|
|
/*---------------------------------------------------------------------------*/ |
/*!Register all the possible sections which we support. |
|
Each section type provides a registration function. This returns a struct |
config_section, which in turn contains a list of config_params. */ |
/*---------------------------------------------------------------------------*/ |
void |
reg_config_secs (void) |
reg_config_secs () |
{ |
reg_config_param (reg_config_sec ("base", NULL, NULL), "include", |
paramt_str, base_include); |
|
reg_generic_sec (); /* JPB */ |
reg_sim_sec (); |
reg_cpu_sec (); |
797,271 → 1584,20
reg_cuc_sec (); |
} |
|
void |
reg_config_param (struct config_section *sec, const char *param, |
enum param_t type, |
void (*param_cb) (union param_val, void *)) |
{ |
struct config_param *new = malloc (sizeof (struct config_param)); |
|
if (!new) |
{ |
fprintf (stderr, "Out-of-memory\n"); |
exit (1); |
} |
|
if (!(new->name = strdup (param))) |
{ |
fprintf (stderr, "Out-of-memory\n"); |
exit (1); |
} |
|
new->func = param_cb; |
new->type = type; |
|
new->next = sec->params; |
sec->params = new; |
} |
|
struct config_section * |
reg_config_sec (const char *section, |
void *(*sec_start) (void), void (*sec_end) (void *)) |
{ |
struct config_section *new = malloc (sizeof (struct config_section)); |
|
if (!new) |
{ |
fprintf (stderr, "Out-of-memory\n"); |
exit (1); |
} |
|
if (!(new->name = strdup (section))) |
{ |
fprintf (stderr, "Out-of-memory\n"); |
exit (1); |
} |
|
new->next = sections; |
new->sec_start = sec_start; |
new->sec_end = sec_end; |
new->params = NULL; |
|
sections = new; |
|
return new; |
} |
|
static void |
switch_param (char *param, struct config_param *cur_param) |
{ |
char *end_p; |
union param_val val; |
|
/* Skip over an = sign if it exists */ |
if (*param == '=') |
{ |
param++; |
while (*param && isspace (*param)) |
param++; |
} |
|
switch (cur_param->type) |
{ |
case paramt_int: |
val.int_val = strtol (param, NULL, 0); |
break; |
case paramt_longlong: |
val.longlong_val = strtoll (param, NULL, 0); |
break; |
case paramt_addr: |
val.addr_val = strtoul (param, NULL, 0); |
break; |
case paramt_str: |
if (*param != '"') |
{ |
fprintf (stderr, |
"Warning: String value for parameter expected: ignored\n"); |
return; |
} |
|
param++; |
end_p = param; |
while (*end_p && (*end_p != '"')) |
end_p++; |
*end_p = '\0'; |
val.str_val = param; |
break; |
case paramt_word: |
end_p = param; |
while (*end_p && !isspace (*end_p)) |
end_p++; |
*end_p = '\0'; |
val.str_val = param; |
break; |
case paramt_none: |
break; |
} |
|
cur_param->func (val, cur_section->dat); |
} |
|
/* Read environment from a script file. Does not fail - assumes default configuration instead. |
The syntax of script file is: |
param = value |
section x |
data |
param = value |
end |
|
Example: |
section mc |
memory_table_file = sim.mem |
enable = 1 |
POC = 0x47892344 |
end |
|
*/ |
|
static void |
read_script_file (const char *filename) |
{ |
FILE *f; |
char *home = getenv ("HOME"); |
char ctmp[STR_SIZE]; |
int local = 1; |
cur_section = NULL; |
|
sprintf (ctmp, "%s/.or1k/%s", home, filename); |
if ((f = fopen (filename, "rt")) || (home && (f = fopen (ctmp, "rt")))) |
{ |
if (config.sim.verbose) |
PRINTF ("Reading script file from '%s'...\n", |
local ? filename : ctmp); |
|
while (!feof (f)) |
{ |
char param[STR_SIZE]; |
if (fscanf (f, "%s ", param) != 1) |
break; |
/* Is this a section? */ |
if (strcmp (param, "section") == 0) |
{ |
struct config_section *cur; |
cur_section = NULL; |
if (fscanf (f, "%s\n", param) != 1) |
{ |
fprintf (stderr, "%s: ERROR: Section name required.\n", |
local ? filename : ctmp); |
exit (1); |
} |
for (cur = sections; cur; cur = cur->next) |
if (strcmp (cur->name, param) == 0) |
{ |
cur_section = cur; |
break; |
} |
if (!cur) |
{ |
fprintf (stderr, |
"Warning: Unknown config section: %s; ignoring.\n", |
param); |
/* just skip section */ |
while (fscanf (f, "%s\n", param) == 1 |
&& strcmp (param, "end")); |
} |
else |
{ |
cur->dat = NULL; |
if (cur->sec_start) |
cur->dat = cur->sec_start (); |
} |
} |
else if (strcmp (param, "end") == 0) |
{ |
if (cur_section->sec_end) |
cur_section->sec_end (cur_section->dat); |
cur_section = NULL; |
} |
else if (strncmp (param, "/*", 2) == 0) |
{ |
char c0 = 0, c1 = 0; |
while (c0 != '*' || c1 != '/') |
{ |
c0 = c1; |
c1 = fgetc (f); |
if (feof (f)) |
{ |
fprintf (stderr, "%s: ERROR: Comment reached EOF.\n", |
local ? filename : ctmp); |
exit (1); |
} |
} |
} |
else |
{ |
struct config_param *cur_param = NULL; |
char *cur_p; |
/* If we have a corrupt file, this could be encountered outside |
a section. So make sure cur_section is defined. */ |
if (cur_section) |
{ |
for (cur_param = cur_section->params; cur_param; |
cur_param = cur_param->next) |
{ |
if (strcmp (cur_param->name, param) == 0) |
{ |
break; |
} |
} |
} |
if (!cur_param) |
{ |
fprintf (stderr, "Warning: Invalid parameter: %s; ignored\n", |
param); |
while (fgetc (f) != '\n' || feof (f)); |
continue; |
} |
|
if (cur_param->type == paramt_none) |
continue; |
|
/* Parse parameter value */ |
cur_p = fgets (param, STR_SIZE, f); |
|
while (*cur_p && isspace (*cur_p)) |
cur_p++; |
|
switch_param (cur_p, cur_param); |
} |
} |
fclose (f); |
} |
else if (config.sim.verbose) |
fprintf (stderr, |
"Warning: Cannot read script file from '%s' of '%s'.\n", |
filename, ctmp); |
} |
|
/* Utility for execution of set sim command. */ |
static int |
set_config (int argc, char **argv) |
{ |
struct config_section *cur; |
struct config_param *cur_param; |
struct config_section *cur_section; |
struct config_param *param; |
|
if (argc < 2) |
return 1; |
|
PRINTF ("sec:%s\n", argv[1]); |
cur_section = NULL; |
for (cur = sections; cur; cur = cur->next) |
if (strcmp (cur->name, argv[1]) == 0) |
{ |
cur_section = cur; |
break; |
} |
cur_section = lookup_section (argv[1]); |
|
if (!cur_section) |
if (NULL == cur_section) |
return 1; |
|
if (argc < 3) |
1069,16 → 1605,16
|
PRINTF ("item:%s\n", argv[2]); |
{ |
for (cur_param = cur->params; cur_param; cur_param = cur_param->next) |
if (strcmp (cur_param->name, argv[2]) == 0) |
for (param = cur_section->params; param; param = param->next) |
if (strcmp (param->name, argv[2]) == 0) |
{ |
break; |
} |
if (!cur_param) |
if (!param) |
return 2; |
|
/* Parse parameter value */ |
if (cur_param->type) |
if (param->type) |
{ |
if (argc < 4) |
return 3; |
1085,7 → 1621,7
PRINTF ("params:%s\n", argv[3]); |
} |
|
switch_param (argv[3], cur_param); |
set_config_param (cur_section, param, argv[3]); |
} |
return 0; |
} |
1095,7 → 1631,7
set_config_command (int argc, char **argv) |
{ |
struct config_section *cur; |
struct config_param *cur_param; |
struct config_param *param; |
|
switch (set_config (argc, argv)) |
{ |
1102,16 → 1638,17
case 1: |
PRINTF |
("Invalid or missing section name. One of valid sections must be specified:\n"); |
for (cur = sections; cur; cur = cur->next) |
for (cur = section_master_list; cur; cur = cur->next) |
PRINTF ("%s ", cur->name); |
PRINTF ("\n"); |
break; |
case 2: |
cur = lookup_section (argv[1]); |
PRINTF |
("Invalid or missing item name. One of valid items must be specified:\n"); |
for (cur_param = cur_section->params; cur_param; |
cur_param = cur_param->next) |
PRINTF ("%s ", cur_param->name); |
for (param = cur->params; param; |
param = param->next) |
PRINTF ("%s ", param->name); |
PRINTF ("\n"); |
break; |
case 3: |