Merge pull request #204 from ozbenh/spi

Add an SPI master flash controller
pull/206/head
Paul Mackerras 5 years ago committed by GitHub
commit bf6cc2a05a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -50,17 +50,13 @@ core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \
loadstore1.vhdl mmu.vhdl dcache.vhdl writeback.vhdl core_debug.vhdl \
core.vhdl

soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \
wishbone_debug_master.vhdl xics.vhdl syscon.vhdl soc.vhdl
soc_files = $(core_files) wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \
wishbone_debug_master.vhdl xics.vhdl syscon.vhdl soc.vhdl \
spi_rxtx.vhdl spi_flash_ctrl.vhdl

soc_sim_files = sim_console.vhdl sim_uart.vhdl sim_bram_helpers.vhdl \
sim_bram.vhdl sim_jtag_socket.vhdl sim_jtag.vhdl dmi_dtm_xilinx.vhdl

unisim_lib = sim-unisim/unisim-obj08.cf
unisim_lib_files = sim-unisim/BSCANE2.vhdl sim-unisim/BUFG.vhdl \
sim-unisim/unisim_vcomponents.vhdl
$(unisim_lib): $(unisim_lib_files)
ghdl -i --std=08 --work=unisim --workdir=sim-unisim $^
soc_sim_files = $(soc_files) sim_console.vhdl sim_uart.vhdl sim_bram_helpers.vhdl \
sim_bram.vhdl sim_jtag_socket.vhdl sim_jtag.vhdl dmi_dtm_xilinx.vhdl

soc_sim_c_files = sim_vhpi_c.c sim_bram_helpers_c.c sim_console_c.c \
sim_jtag_socket_c.c
@ -69,12 +65,39 @@ soc_sim_obj_files=$(soc_sim_c_files:.c=.o)
comma := ,
soc_sim_link=$(patsubst %,-Wl$(comma)%,$(soc_sim_obj_files))

unisim_dir = sim-unisim
unisim_lib = $(unisim_dir)/unisim-obj08.cf
unisim_lib_files = $(unisim_dir)/BSCANE2.vhdl $(unisim_dir)/BUFG.vhdl \
$(unisim_dir)/unisim_vcomponents.vhdl
$(unisim_lib): $(unisim_lib_files)
ghdl -i --std=08 --work=unisim --workdir=$(unisim_dir) $^
GHDLFLAGS += -P$(unisim_dir)

core_tbs = multiply_tb divider_tb rotator_tb countzero_tb
soc_tbs = core_tb icache_tb dcache_tb dmi_dtm_tb wishbone_bram_tb
soc_flash_tbs = core_flash_tb
soc_dram_tbs = dram_tb core_dram_tb

$(soc_tbs): %: $(core_files) $(soc_files) $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) %.vhdl
$(GHDL) -c $(GHDLFLAGS) -Psim-unisim $(soc_sim_link) $(core_files) $(soc_files) $(soc_sim_files) $@.vhdl -e $@
ifneq ($(FLASH_MODEL_PATH),)
fmf_dir = $(FLASH_MODEL_PATH)/fmf
fmf_lib = $(fmf_dir)/fmf-obj08.cf
fmf_lib_files = $(wildcard $(fmf_dir)/*.vhd)
GHDLFLAGS += -P$(fmf_dir)
$(fmf_lib): $(fmf_lib_files)
ghdl -i --std=08 --work=fmf --workdir=$(fmf_dir) $^

flash_model_files=$(FLASH_MODEL_PATH)/s25fl128s.vhd
flash_model_files: $(fmf_lib)
else
flash_model_files=sim_no_flash.vhdl
fmf_lib=
endif

$(soc_flash_tbs): %: $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) $(fmf_lib) $(flash_model_files) %.vhdl
$(GHDL) -c $(GHDLFLAGS) $(soc_sim_link) $(soc_sim_files) $(flash_model_files) $@.vhdl $(unisim_files) -e $@

$(soc_tbs): %: $(soc_sim_files) $(soc_sim_obj_files) $(unisim_lib) %.vhdl
$(GHDL) -c $(GHDLFLAGS) $(soc_sim_link) $(soc_sim_files) $@.vhdl -e $@

$(core_tbs): %: $(core_files) glibc_random.vhdl glibc_random_helpers.vhdl %.vhdl
$(GHDL) -c $(GHDLFLAGS) $(core_files) glibc_random.vhdl glibc_random_helpers.vhdl $@.vhdl -e $@
@ -106,8 +129,8 @@ soc_dram_sim_obj_files = $(soc_sim_obj_files) sim_litedram_c.o
dram_link_files=-Wl,obj_dir/Vlitedram_core__ALL.a -Wl,obj_dir/verilated.o -Wl,obj_dir/verilated_vcd_c.o -Wl,-lstdc++
soc_dram_sim_link=$(patsubst %,-Wl$(comma)%,$(soc_dram_sim_obj_files)) $(dram_link_files)

$(soc_dram_tbs): %: $(core_files) $(soc_dram_files) $(soc_dram_sim_files) $(soc_dram_sim_obj_files) $(unisim_lib) %.vhdl
$(GHDL) -c $(GHDLFLAGS) -Psim-unisim $(soc_dram_sim_link) $(core_files) $(soc_dram_files) $(soc_dram_sim_files) $@.vhdl -e $@
$(soc_dram_tbs): %: $(soc_dram_files) $(soc_dram_sim_files) $(soc_dram_sim_obj_files) $(flash_model_files) $(unisim_lib) $(fmf_lib) %.vhdl
$(GHDL) -c $(GHDLFLAGS) $(soc_dram_sim_link) $(soc_dram_files) $(soc_dram_sim_files) $(flash_model_files) $@.vhdl -e $@
endif

# Hello world

@ -5,6 +5,7 @@ use ieee.numeric_std.all;
library work;
use work.common.all;
use work.wishbone_types.all;
use work.utils.all;

entity core_dram_tb is
generic (
@ -31,6 +32,17 @@ architecture behave of core_dram_tb is
signal wb_dram_is_init : std_ulogic;
signal core_alt_reset : std_ulogic;

-- SPI
signal spi_sck : std_ulogic;
signal spi_cs_n : std_ulogic := '1';
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
signal fl_hold_n : std_logic;
signal fl_wp_n : std_logic;
signal fl_mosi : std_logic;
signal fl_miso : std_logic;

-- ROM size
function get_rom_size return natural is
begin
@ -53,7 +65,10 @@ begin
HAS_DRAM => true,
DRAM_SIZE => 256 * 1024 * 1024,
DRAM_INIT_SIZE => ROM_SIZE,
CLK_FREQ => 100000000
CLK_FREQ => 100000000,
HAS_SPI_FLASH => true,
SPI_FLASH_DLINES => 4,
SPI_FLASH_OFFSET => 0
)
port map(
rst => soc_rst,
@ -66,9 +81,44 @@ begin
wb_dram_ctrl_out => wb_dram_ctrl_out,
wb_dram_is_csr => wb_dram_is_csr,
wb_dram_is_init => wb_dram_is_init,
spi_flash_sck => spi_sck,
spi_flash_cs_n => spi_cs_n,
spi_flash_sdat_o => spi_sdat_o,
spi_flash_sdat_oe => spi_sdat_oe,
spi_flash_sdat_i => spi_sdat_i,
alt_reset => core_alt_reset
);

flash: entity work.s25fl128s
generic map (
TimingModel => "S25FL128SAGNFI000_R_30pF",
LongTimming => false,
tdevice_PU => 10 ns,
tdevice_PP256 => 100 ns,
tdevice_PP512 => 100 ns,
tdevice_WRR => 100 ns,
UserPreload => TRUE
)
port map(
SCK => spi_sck,
SI => fl_mosi,
CSNeg => spi_cs_n,
HOLDNeg => fl_hold_n,
WPNeg => fl_wp_n,
RSTNeg => '1',
SO => fl_miso
);

fl_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
fl_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
fl_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
fl_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else '1' when spi_sdat_oe(0) = '1' else 'Z';

spi_sdat_i(0) <= fl_mosi;
spi_sdat_i(1) <= fl_miso;
spi_sdat_i(2) <= fl_wp_n;
spi_sdat_i(3) <= fl_hold_n;

dram: entity work.litedram_wrapper
generic map(
DRAM_ABITS => 24,

@ -0,0 +1,119 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.common.all;
use work.wishbone_types.all;

entity core_flash_tb is
end core_flash_tb;

architecture behave of core_flash_tb is
signal clk, rst: std_logic;

-- testbench signals
constant clk_period : time := 10 ns;

-- Dummy DRAM
signal wb_dram_in : wishbone_master_out;
signal wb_dram_out : wishbone_slave_out;
signal wb_dram_ctrl_in : wb_io_master_out;
signal wb_dram_ctrl_out : wb_io_slave_out;

-- SPI
signal spi_sck : std_ulogic;
signal spi_cs_n : std_ulogic := '1';
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
signal fl_hold_n : std_logic;
signal fl_wp_n : std_logic;
signal fl_mosi : std_logic;
signal fl_miso : std_logic;
begin

soc0: entity work.soc
generic map(
SIM => true,
MEMORY_SIZE => (384*1024),
RAM_INIT_FILE => "main_ram.bin",
RESET_LOW => false,
CLK_FREQ => 100000000,
HAS_SPI_FLASH => true,
SPI_FLASH_DLINES => 4,
SPI_FLASH_OFFSET => 0
)
port map(
rst => rst,
system_clk => clk,
uart0_rxd => '0',
uart0_txd => open,
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
wb_dram_ctrl_in => wb_dram_ctrl_in,
wb_dram_ctrl_out => wb_dram_ctrl_out,
spi_flash_sck => spi_sck,
spi_flash_cs_n => spi_cs_n,
spi_flash_sdat_o => spi_sdat_o,
spi_flash_sdat_oe => spi_sdat_oe,
spi_flash_sdat_i => spi_sdat_i,
alt_reset => '0'
);

flash: entity work.s25fl128s
generic map (
TimingModel => "S25FL128SAGNFI000_R_30pF",
LongTimming => false,
tdevice_PU => 10 ns,
tdevice_PP256 => 100 ns,
tdevice_PP512 => 100 ns,
tdevice_WRR => 100 ns
)
port map(
SCK => spi_sck,
SI => fl_mosi,
CSNeg => spi_cs_n,
HOLDNeg => fl_hold_n,
WPNeg => fl_wp_n,
RSTNeg => '1',
SO => fl_miso
);

fl_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
fl_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
fl_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
fl_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else '1' when spi_sdat_oe(0) = '1' else 'Z';

spi_sdat_i(0) <= fl_mosi;
spi_sdat_i(1) <= fl_miso;
spi_sdat_i(2) <= fl_wp_n;
spi_sdat_i(3) <= fl_hold_n;
clk_process: process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;

rst_process: process
begin
rst <= '1';
wait for 10*clk_period;
rst <= '0';
wait;
end process;

jtag: entity work.sim_jtag;

-- Dummy DRAM
wb_dram_out.ack <= wb_dram_in.cyc and wb_dram_in.stb;
wb_dram_out.dat <= x"FFFFFFFFFFFFFFFF";
wb_dram_out.stall <= '0';
wb_dram_ctrl_out.ack <= wb_dram_ctrl_in.cyc and wb_dram_ctrl_in.stb;
wb_dram_ctrl_out.dat <= x"FFFFFFFF";
wb_dram_ctrl_out.stall <= '0';

end;

@ -20,6 +20,9 @@ architecture behave of core_tb is
signal wb_dram_out : wishbone_slave_out;
signal wb_dram_ctrl_in : wb_io_master_out;
signal wb_dram_ctrl_out : wb_io_slave_out;

-- Dummy SPI
signal spi_sdat_i : std_ulogic_vector(0 downto 0);
begin

soc0: entity work.soc
@ -28,19 +31,26 @@ begin
MEMORY_SIZE => (384*1024),
RAM_INIT_FILE => "main_ram.bin",
RESET_LOW => false,
CLK_FREQ => 100000000
CLK_FREQ => 100000000,
HAS_SPI_FLASH => false
)
port map(
rst => rst,
system_clk => clk,
uart0_rxd => '0',
uart0_txd => open,
spi_flash_sck => open,
spi_flash_cs_n => open,
spi_flash_sdat_o => open,
spi_flash_sdat_oe => open,
spi_flash_sdat_i => spi_sdat_i,
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
wb_dram_ctrl_in => wb_dram_ctrl_in,
wb_dram_ctrl_out => wb_dram_ctrl_out,
alt_reset => '0'
);
spi_sdat_i(0) <= '1';

clk_process: process
begin

@ -26,6 +26,22 @@ set_property -dict { PACKAGE_PIN E1 IOSTANDARD LVCMOS33 } [get_ports { led0_b }
set_property -dict { PACKAGE_PIN F6 IOSTANDARD LVCMOS33 } [get_ports { led0_g }];
set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { led0_r }];

################################################################################
# SPI Flash
################################################################################

set_property -dict { PACKAGE_PIN L13 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_cs_n }];
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_clk }];
set_property -dict { PACKAGE_PIN K17 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_mosi }];
set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_miso }];
set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_wp_n }];
set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_hold_n }];

# Put registers into IOBs to improve timing
set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/*sck_1*}]
set_property IOB true [get_cells -hierarchical -filter {NAME =~*/spi_rxtx/dat_i_l*}]


################################################################################
# DRAM (generated by LiteX)
################################################################################

@ -25,6 +25,16 @@ set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports uart_main_rx
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { led0 }];
set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { led1 }];

################################################################################
# SPI Flash
################################################################################

set_property -dict { PACKAGE_PIN T19 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_cs_n }];
set_property -dict { PACKAGE_PIN P22 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_mosi }];
set_property -dict { PACKAGE_PIN R22 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_miso }];
set_property -dict { PACKAGE_PIN P21 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_wp_n }];
set_property -dict { PACKAGE_PIN R21 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_hold_n }];

################################################################################
# DRAM (generated by LiteX)
################################################################################

@ -16,7 +16,11 @@ entity toplevel is
CLK_FREQUENCY : positive := 100000000;
USE_LITEDRAM : boolean := false;
NO_BRAM : boolean := false;
DISABLE_FLATTEN_CORE : boolean := false
DISABLE_FLATTEN_CORE : boolean := false;
SCLK_STARTUPE2 : boolean := false;
SPI_FLASH_OFFSET : integer := 4194304;
SPI_FLASH_DEF_CKDV : natural := 1;
SPI_FLASH_DEF_QUAD : boolean := true
);
port(
ext_clk : in std_ulogic;
@ -31,6 +35,14 @@ entity toplevel is
led0_g : out std_ulogic;
led0_r : out std_ulogic;

-- SPI
spi_flash_cs_n : out std_ulogic;
spi_flash_clk : out std_ulogic;
spi_flash_mosi : inout std_ulogic;
spi_flash_miso : inout std_ulogic;
spi_flash_wp_n : inout std_ulogic;
spi_flash_hold_n : inout std_ulogic;

-- DRAM wires
ddram_a : out std_ulogic_vector(13 downto 0);
ddram_ba : out std_ulogic_vector(2 downto 0);
@ -81,6 +93,13 @@ architecture behaviour of toplevel is
-- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
signal pwm_counter : std_ulogic_vector(8 downto 0);

-- SPI flash
signal spi_sck : std_ulogic;
signal spi_cs_n : std_ulogic;
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
signal spi_sdat_i : std_ulogic_vector(3 downto 0);

-- Fixup various memory sizes based on generics
function get_bram_size return natural is
begin
@ -115,13 +134,30 @@ begin
HAS_DRAM => USE_LITEDRAM,
DRAM_SIZE => 256 * 1024 * 1024,
DRAM_INIT_SIZE => PAYLOAD_SIZE,
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
HAS_SPI_FLASH => true,
SPI_FLASH_DLINES => 4,
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD
)
port map (
-- System signals
system_clk => system_clk,
rst => soc_rst,

-- UART signals
uart0_txd => uart_main_tx,
uart0_rxd => uart_main_rx,

-- SPI signals
spi_flash_sck => spi_sck,
spi_flash_cs_n => spi_cs_n,
spi_flash_sdat_o => spi_sdat_o,
spi_flash_sdat_oe => spi_sdat_oe,
spi_flash_sdat_i => spi_sdat_i,

-- DRAM wishbone
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
wb_dram_ctrl_in => wb_dram_ctrl_in,
@ -131,6 +167,43 @@ begin
alt_reset => core_alt_reset
);

-- SPI Flash
--
-- Note: Unlike many other boards, the SPI flash on the Arty has
-- an actual pin to generate the clock and doesn't require to use
-- the STARTUPE2 primitive.
--
spi_flash_cs_n <= spi_cs_n;
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
spi_sdat_i(0) <= spi_flash_mosi;
spi_sdat_i(1) <= spi_flash_miso;
spi_sdat_i(2) <= spi_flash_wp_n;
spi_sdat_i(3) <= spi_flash_hold_n;

spi_sclk_startupe2: if SCLK_STARTUPE2 generate
spi_flash_clk <= 'Z';

STARTUPE2_INST: STARTUPE2
port map (
CLK => '0',
GSR => '0',
GTS => '0',
KEYCLEARB => '0',
PACK => '0',
USRCCLKO => spi_sck,
USRCCLKTS => '0',
USRDONEO => '1',
USRDONETS => '0'
);
end generate;

spi_direct_sclk: if not SCLK_STARTUPE2 generate
spi_flash_clk <= spi_sck;
end generate;

nodram: if not USE_LITEDRAM generate
signal ddram_clk_dummy : std_ulogic;
begin

@ -78,13 +78,19 @@ begin
RESET_LOW => RESET_LOW,
SIM => false,
CLK_FREQ => CLK_FREQUENCY,
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
HAS_SPI => false
)
port map (
system_clk => system_clk,
rst => soc_rst,
uart0_txd => uart0_txd,
uart0_rxd => uart0_rxd,
spi0_sck => open,
spi0_cs_n => open,
spi0_sdat_o => open,
spi0_sdat_oe => open,
spi0_sdat_i => '1',
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
wb_dram_ctrl_in => wb_dram_ctrl_in,

@ -16,7 +16,10 @@ entity toplevel is
CLK_FREQUENCY : positive := 100000000;
USE_LITEDRAM : boolean := false;
NO_BRAM : boolean := false;
DISABLE_FLATTEN_CORE : boolean := false
DISABLE_FLATTEN_CORE : boolean := false;
SPI_FLASH_OFFSET : integer := 10485760;
SPI_FLASH_DEF_CKDV : natural := 1;
SPI_FLASH_DEF_QUAD : boolean := true
);
port(
ext_clk : in std_ulogic;
@ -30,6 +33,13 @@ entity toplevel is
led0 : out std_logic;
led1 : out std_logic;

-- SPI
spi_flash_cs_n : out std_ulogic;
spi_flash_mosi : inout std_ulogic;
spi_flash_miso : inout std_ulogic;
spi_flash_wp_n : inout std_ulogic;
spi_flash_hold_n : inout std_ulogic;

-- DRAM wires
ddram_a : out std_logic_vector(14 downto 0);
ddram_ba : out std_logic_vector(2 downto 0);
@ -71,6 +81,13 @@ architecture behaviour of toplevel is
-- Control/status
signal core_alt_reset : std_ulogic;

-- SPI flash
signal spi_sck : std_ulogic;
signal spi_cs_n : std_ulogic;
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
signal spi_sdat_i : std_ulogic_vector(3 downto 0);

-- Fixup various memory sizes based on generics
function get_bram_size return natural is
begin
@ -105,13 +122,30 @@ begin
HAS_DRAM => USE_LITEDRAM,
DRAM_SIZE => 512 * 1024 * 1024,
DRAM_INIT_SIZE => PAYLOAD_SIZE,
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
HAS_SPI_FLASH => true,
SPI_FLASH_DLINES => 4,
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD
)
port map (
-- System signals
system_clk => system_clk,
rst => soc_rst,

-- UART signals
uart0_txd => uart_main_tx,
uart0_rxd => uart_main_rx,

-- SPI signals
spi_flash_sck => spi_sck,
spi_flash_cs_n => spi_cs_n,
spi_flash_sdat_o => spi_sdat_o,
spi_flash_sdat_oe => spi_sdat_oe,
spi_flash_sdat_i => spi_sdat_i,

-- DRAM wishbone
wb_dram_in => wb_dram_in,
wb_dram_out => wb_dram_out,
wb_dram_ctrl_in => wb_dram_ctrl_in,
@ -121,6 +155,32 @@ begin
alt_reset => core_alt_reset
);

-- SPI Flash. The SPI clk needs to be fed through the STARTUPE2
-- primitive of the FPGA as it's not a normal pin
--
spi_flash_cs_n <= spi_cs_n;
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
spi_sdat_i(0) <= spi_flash_mosi;
spi_sdat_i(1) <= spi_flash_miso;
spi_sdat_i(2) <= spi_flash_wp_n;
spi_sdat_i(3) <= spi_flash_hold_n;

STARTUPE2_INST: STARTUPE2
port map (
CLK => '0',
GSR => '0',
GTS => '0',
KEYCLEARB => '0',
PACK => '0',
USRCCLKO => spi_sck,
USRCCLKTS => '0',
USRDONEO => '1',
USRDONETS => '0'
);

nodram: if not USE_LITEDRAM generate
signal ddram_clk_dummy : std_ulogic;
begin

@ -12,8 +12,10 @@
#define SYSCON_BASE 0xc0000000 /* System control regs */
#define UART_BASE 0xc0002000 /* UART */
#define XICS_BASE 0xc0004000 /* Interrupt controller */
#define SPI_FCTRL_BASE 0xc0006000 /* SPI flash controller registers */
#define DRAM_CTRL_BASE 0xc0100000 /* LiteDRAM control registers */
#define DRAM_INIT_BASE 0xf0000000 /* Internal DRAM init firmware */
#define SPI_FLASH_BASE 0xf0000000 /* SPI Flash memory map */
#define DRAM_INIT_BASE 0xff000000 /* Internal DRAM init firmware */

/*
* Register definitions for the syscon registers
@ -24,6 +26,7 @@
#define SYS_REG_INFO_HAS_UART (1ull << 0)
#define SYS_REG_INFO_HAS_DRAM (1ull << 1)
#define SYS_REG_INFO_HAS_BRAM (1ull << 2)
#define SYS_REG_INFO_HAS_SPI_FLASH (1ull << 3)
#define SYS_REG_BRAMINFO 0x10
#define SYS_REG_BRAMINFO_SIZE_MASK 0xfffffffffffffull
#define SYS_REG_DRAMINFO 0x18
@ -35,6 +38,10 @@
#define SYS_REG_CTRL_CORE_RESET (1ull << 1)
#define SYS_REG_CTRL_SOC_RESET (1ull << 2)
#define SYS_REG_DRAMINITINFO 0x30
#define SYS_REG_SPI_INFO 0x38
#define SYS_REG_SPI_INFO_FLASH_OFF_MASK 0xffffffff



/*
* Register definitions for the potato UART
@ -49,5 +56,32 @@
#define POTATO_CONSOLE_CLOCK_DIV 0x18
#define POTATO_CONSOLE_IRQ_EN 0x20

/*
* Register definitions for the SPI controller
*/
#define SPI_REG_DATA 0x00 /* Byte access: single wire transfer */
#define SPI_REG_DATA_DUAL 0x01 /* Byte access: dual wire transfer */
#define SPI_REG_DATA_QUAD 0x02 /* Byte access: quad wire transfer */
#define SPI_REG_CTRL 0x04 /* Reset and manual mode control */
#define SPI_REG_CTRL_RESET 0x01 /* reset all registers */
#define SPI_REG_CTRL_MANUAL_CS 0x02 /* assert CS, enable manual mode */
#define SPI_REG_CTRL_CKDIV_SHIFT 8 /* clock div */
#define SPI_REG_CTRL_CKDIV_MASK (0xff << SPI_REG_CTRL_CKDIV_SHIFT)
#define SPI_REG_AUTO_CFG 0x08 /* Automatic map configuration */
#define SPI_REG_AUTO_CFG_CMD_SHIFT 0 /* Command to use for reads */
#define SPI_REG_AUTO_CFG_CMD_MASK (0xff << SPI_REG_AUTO_CFG_CMD_SHIFT)
#define SPI_REG_AUTO_CFG_DUMMIES_SHIFT 8 /* # dummy cycles */
#define SPI_REG_AUTO_CFG_DUMMIES_MASK (0x7 << SPI_REG_AUTO_CFG_DUMMIES_SHIFT)
#define SPI_REG_AUTO_CFG_MODE_SHIFT 11 /* SPI wire mode */
#define SPI_REG_AUTO_CFG_MODE_MASK (0x3 << SPI_REG_AUTO_CFG_MODE_SHIFT)
#define SPI_REG_AUT_CFG_MODE_SINGLE (0 << 11)
#define SPI_REG_AUT_CFG_MODE_DUAL (2 << 11)
#define SPI_REG_AUT_CFG_MODE_QUAD (3 << 11)
#define SPI_REG_AUTO_CFG_ADDR4 (1u << 13) /* 3 or 4 addr bytes */
#define SPI_REG_AUTO_CFG_CKDIV_SHIFT 16 /* clock div */
#define SPI_REG_AUTO_CFG_CKDIV_MASK (0xff << SPI_REG_AUTO_CFG_CKDIV_SHIFT)
#define SPI_REG_AUTO_CFG_CSTOUT_SHIFT 24 /* CS timeout */
#define SPI_REG_AUTO_CFG_CSTOUT_MASK (0x3f << SPI_REG_AUTO_CFG_CSTOUT_SHIFT)


#endif /* __MICROWATT_SOC_H */

@ -14,7 +14,7 @@
* limitations under the License.
*/

#define STACK_TOP 0xf0004000
#define STACK_TOP 0xff004000

#define FIXUP_ENDIAN \
tdi 0,0,0x48; /* Reverse endian of b . + 8 */ \
@ -50,7 +50,8 @@ start:
LOAD_IMM64(%r12, main)
mtctr %r12,
bctrl
ba 0
mtctr %r3
bctr

/* XXX: litedram init should not take exceptions, maybe we could get
* rid of these to save space, along with a core tweak to suppress

@ -0,0 +1,248 @@
/*-
* Copyright (c) 1996-1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/

#ifndef _SYS_ELF64_H_
#define _SYS_ELF64_H_ 1

#include <elf_common.h>

/*
* ELF definitions common to all 64-bit architectures.
*/

typedef uint64_t Elf64_Addr;
typedef uint16_t Elf64_Half;
typedef uint64_t Elf64_Off;
typedef int32_t Elf64_Sword;
typedef int64_t Elf64_Sxword;
typedef uint32_t Elf64_Word;
typedef uint64_t Elf64_Lword;
typedef uint64_t Elf64_Xword;

/*
* Types of dynamic symbol hash table bucket and chain elements.
*
* This is inconsistent among 64 bit architectures, so a machine dependent
* typedef is required.
*/

typedef Elf64_Word Elf64_Hashelt;

/* Non-standard class-dependent datatype used for abstraction. */
typedef Elf64_Xword Elf64_Size;
typedef Elf64_Sxword Elf64_Ssize;

/*
* ELF header.
*/

typedef struct {
unsigned char e_ident[EI_NIDENT]; /* File identification. */
Elf64_Half e_type; /* File type. */
Elf64_Half e_machine; /* Machine architecture. */
Elf64_Word e_version; /* ELF format version. */
Elf64_Addr e_entry; /* Entry point. */
Elf64_Off e_phoff; /* Program header file offset. */
Elf64_Off e_shoff; /* Section header file offset. */
Elf64_Word e_flags; /* Architecture-specific flags. */
Elf64_Half e_ehsize; /* Size of ELF header in bytes. */
Elf64_Half e_phentsize; /* Size of program header entry. */
Elf64_Half e_phnum; /* Number of program header entries. */
Elf64_Half e_shentsize; /* Size of section header entry. */
Elf64_Half e_shnum; /* Number of section header entries. */
Elf64_Half e_shstrndx; /* Section name strings section. */
} Elf64_Ehdr;

/*
* Section header.
*/

typedef struct {
Elf64_Word sh_name; /* Section name (index into the
section header string table). */
Elf64_Word sh_type; /* Section type. */
Elf64_Xword sh_flags; /* Section flags. */
Elf64_Addr sh_addr; /* Address in memory image. */
Elf64_Off sh_offset; /* Offset in file. */
Elf64_Xword sh_size; /* Size in bytes. */
Elf64_Word sh_link; /* Index of a related section. */
Elf64_Word sh_info; /* Depends on section type. */
Elf64_Xword sh_addralign; /* Alignment in bytes. */
Elf64_Xword sh_entsize; /* Size of each entry in section. */
} Elf64_Shdr;

/*
* Program header.
*/

typedef struct {
Elf64_Word p_type; /* Entry type. */
Elf64_Word p_flags; /* Access permission flags. */
Elf64_Off p_offset; /* File offset of contents. */
Elf64_Addr p_vaddr; /* Virtual address in memory image. */
Elf64_Addr p_paddr; /* Physical address (not used). */
Elf64_Xword p_filesz; /* Size of contents in file. */
Elf64_Xword p_memsz; /* Size of contents in memory. */
Elf64_Xword p_align; /* Alignment in memory and file. */
} Elf64_Phdr;

/*
* Dynamic structure. The ".dynamic" section contains an array of them.
*/

typedef struct {
Elf64_Sxword d_tag; /* Entry type. */
union {
Elf64_Xword d_val; /* Integer value. */
Elf64_Addr d_ptr; /* Address value. */
} d_un;
} Elf64_Dyn;

/*
* Relocation entries.
*/

/* Relocations that don't need an addend field. */
typedef struct {
Elf64_Addr r_offset; /* Location to be relocated. */
Elf64_Xword r_info; /* Relocation type and symbol index. */
} Elf64_Rel;

/* Relocations that need an addend field. */
typedef struct {
Elf64_Addr r_offset; /* Location to be relocated. */
Elf64_Xword r_info; /* Relocation type and symbol index. */
Elf64_Sxword r_addend; /* Addend. */
} Elf64_Rela;

/* Macros for accessing the fields of r_info. */
#define ELF64_R_SYM(info) ((info) >> 32)
#define ELF64_R_TYPE(info) ((info) & 0xffffffffL)

/* Macro for constructing r_info from field values. */
#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))

#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40)
#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56)
#define ELF64_R_TYPE_INFO(data, type) \
(((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))

/*
* Note entry header
*/
typedef Elf_Note Elf64_Nhdr;

/*
* Move entry
*/
typedef struct {
Elf64_Lword m_value; /* symbol value */
Elf64_Xword m_info; /* size + index */
Elf64_Xword m_poffset; /* symbol offset */
Elf64_Half m_repeat; /* repeat count */
Elf64_Half m_stride; /* stride info */
} Elf64_Move;

#define ELF64_M_SYM(info) ((info)>>8)
#define ELF64_M_SIZE(info) ((unsigned char)(info))
#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))

/*
* Hardware/Software capabilities entry
*/
typedef struct {
Elf64_Xword c_tag; /* how to interpret value */
union {
Elf64_Xword c_val;
Elf64_Addr c_ptr;
} c_un;
} Elf64_Cap;

/*
* Symbol table entries.
*/

typedef struct {
Elf64_Word st_name; /* String table index of name. */
unsigned char st_info; /* Type and binding information. */
unsigned char st_other; /* Reserved (not used). */
Elf64_Half st_shndx; /* Section index of symbol. */
Elf64_Addr st_value; /* Symbol value. */
Elf64_Xword st_size; /* Size of associated object. */
} Elf64_Sym;

/* Macros for accessing the fields of st_info. */
#define ELF64_ST_BIND(info) ((info) >> 4)
#define ELF64_ST_TYPE(info) ((info) & 0xf)

/* Macro for constructing st_info from field values. */
#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))

/* Macro for accessing the fields of st_other. */
#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3)

/* Structures used by Sun & GNU-style symbol versioning. */
typedef struct {
Elf64_Half vd_version;
Elf64_Half vd_flags;
Elf64_Half vd_ndx;
Elf64_Half vd_cnt;
Elf64_Word vd_hash;
Elf64_Word vd_aux;
Elf64_Word vd_next;
} Elf64_Verdef;

typedef struct {
Elf64_Word vda_name;
Elf64_Word vda_next;
} Elf64_Verdaux;

typedef struct {
Elf64_Half vn_version;
Elf64_Half vn_cnt;
Elf64_Word vn_file;
Elf64_Word vn_aux;
Elf64_Word vn_next;
} Elf64_Verneed;

typedef struct {
Elf64_Word vna_hash;
Elf64_Half vna_flags;
Elf64_Half vna_other;
Elf64_Word vna_name;
Elf64_Word vna_next;
} Elf64_Vernaux;

typedef Elf64_Half Elf64_Versym;

typedef struct {
Elf64_Half si_boundto; /* direct bindings - symbol bound to */
Elf64_Half si_flags; /* per symbol flags */
} Elf64_Syminfo;

#endif /* !_SYS_ELF64_H_ */

@ -0,0 +1,994 @@
/*-
* Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien
* Copyright (c) 1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/

#ifndef _SYS_ELF_COMMON_H_
#define _SYS_ELF_COMMON_H_ 1

/*
* ELF definitions that are independent of architecture or word size.
*/

/*
* Note header. The ".note" section contains an array of notes. Each
* begins with this header, aligned to a word boundary. Immediately
* following the note header is n_namesz bytes of name, padded to the
* next word boundary. Then comes n_descsz bytes of descriptor, again
* padded to a word boundary. The values of n_namesz and n_descsz do
* not include the padding.
*/

typedef struct {
uint32_t n_namesz; /* Length of name. */
uint32_t n_descsz; /* Length of descriptor. */
uint32_t n_type; /* Type of this note. */
} Elf_Note;

/*
* The header for GNU-style hash sections.
*/

typedef struct {
uint32_t gh_nbuckets; /* Number of hash buckets. */
uint32_t gh_symndx; /* First visible symbol in .dynsym. */
uint32_t gh_maskwords; /* #maskwords used in bloom filter. */
uint32_t gh_shift2; /* Bloom filter shift count. */
} Elf_GNU_Hash_Header;

/* Indexes into the e_ident array. Keep synced with
http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
#define EI_MAG0 0 /* Magic number, byte 0. */
#define EI_MAG1 1 /* Magic number, byte 1. */
#define EI_MAG2 2 /* Magic number, byte 2. */
#define EI_MAG3 3 /* Magic number, byte 3. */
#define EI_CLASS 4 /* Class of machine. */
#define EI_DATA 5 /* Data format. */
#define EI_VERSION 6 /* ELF format version. */
#define EI_OSABI 7 /* Operating system / ABI identification */
#define EI_ABIVERSION 8 /* ABI version */
#define OLD_EI_BRAND 8 /* Start of architecture identification. */
#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
#define EI_NIDENT 16 /* Size of e_ident array. */

/* Values for the magic number bytes. */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF" /* magic string */
#define SELFMAG 4 /* magic string size */

/* Values for e_ident[EI_VERSION] and e_version. */
#define EV_NONE 0
#define EV_CURRENT 1

/* Values for e_ident[EI_CLASS]. */
#define ELFCLASSNONE 0 /* Unknown class. */
#define ELFCLASS32 1 /* 32-bit architecture. */
#define ELFCLASS64 2 /* 64-bit architecture. */

/* Values for e_ident[EI_DATA]. */
#define ELFDATANONE 0 /* Unknown data format. */
#define ELFDATA2LSB 1 /* 2's complement little-endian. */
#define ELFDATA2MSB 2 /* 2's complement big-endian. */

/* Values for e_ident[EI_OSABI]. */
#define ELFOSABI_NONE 0 /* UNIX System V ABI */
#define ELFOSABI_HPUX 1 /* HP-UX operating system */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* GNU/Linux */
#define ELFOSABI_HURD 4 /* GNU/Hurd */
#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
#define ELFOSABI_SOLARIS 6 /* Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
#define ELFOSABI_OPENVMS 13 /* Open VMS */
#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
#define ELFOSABI_AROS 15 /* Amiga Research OS */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */

#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */

/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)

/* Values for e_type. */
#define ET_NONE 0 /* Unknown type. */
#define ET_REL 1 /* Relocatable. */
#define ET_EXEC 2 /* Executable. */
#define ET_DYN 3 /* Shared object. */
#define ET_CORE 4 /* Core file. */
#define ET_LOOS 0xfe00 /* First operating system specific. */
#define ET_HIOS 0xfeff /* Last operating system-specific. */
#define ET_LOPROC 0xff00 /* First processor-specific. */
#define ET_HIPROC 0xffff /* Last processor-specific. */

/* Values for e_machine. */
#define EM_NONE 0 /* Unknown machine. */
#define EM_M32 1 /* AT&T WE32100. */
#define EM_SPARC 2 /* Sun SPARC. */
#define EM_386 3 /* Intel i386. */
#define EM_68K 4 /* Motorola 68000. */
#define EM_88K 5 /* Motorola 88000. */
#define EM_860 7 /* Intel i860. */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
#define EM_S370 9 /* IBM System/370. */
#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
#define EM_PARISC 15 /* HP PA-RISC. */
#define EM_VPP500 17 /* Fujitsu VPP500. */
#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
#define EM_960 19 /* Intel 80960. */
#define EM_PPC 20 /* PowerPC 32-bit. */
#define EM_PPC64 21 /* PowerPC 64-bit. */
#define EM_S390 22 /* IBM System/390. */
#define EM_V800 36 /* NEC V800. */
#define EM_FR20 37 /* Fujitsu FR20. */
#define EM_RH32 38 /* TRW RH-32. */
#define EM_RCE 39 /* Motorola RCE. */
#define EM_ARM 40 /* ARM. */
#define EM_SH 42 /* Hitachi SH. */
#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
#define EM_ARC 45 /* Argonaut RISC Core. */
#define EM_H8_300 46 /* Hitachi H8/300. */
#define EM_H8_300H 47 /* Hitachi H8/300H. */
#define EM_H8S 48 /* Hitachi H8S. */
#define EM_H8_500 49 /* Hitachi H8/500. */
#define EM_IA_64 50 /* Intel IA-64 Processor. */
#define EM_MIPS_X 51 /* Stanford MIPS-X. */
#define EM_COLDFIRE 52 /* Motorola ColdFire. */
#define EM_68HC12 53 /* Motorola M68HC12. */
#define EM_MMA 54 /* Fujitsu MMA. */
#define EM_PCP 55 /* Siemens PCP. */
#define EM_NCPU 56 /* Sony nCPU. */
#define EM_NDR1 57 /* Denso NDR1 microprocessor. */
#define EM_STARCORE 58 /* Motorola Star*Core processor. */
#define EM_ME16 59 /* Toyota ME16 processor. */
#define EM_ST100 60 /* STMicroelectronics ST100 processor. */
#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */
#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
#define EM_PDSP 63 /* Sony DSP Processor. */
#define EM_FX66 66 /* Siemens FX66 microcontroller. */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16
microcontroller. */
#define EM_ST7 68 /* STmicroelectronics ST7 8-bit
microcontroller. */
#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */
#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */
#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */
#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */
#define EM_SVX 73 /* Silicon Graphics SVx. */
#define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */
#define EM_VAX 75 /* Digital VAX. */
#define EM_CRIS 76 /* Axis Communications 32-bit embedded
processor. */
#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded
processor. */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */
#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */
#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */
#define EM_HUANY 81 /* Harvard University machine-independent
object files. */
#define EM_PRISM 82 /* SiTera Prism. */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */
#define EM_FR30 84 /* Fujitsu FR30. */
#define EM_D10V 85 /* Mitsubishi D10V. */
#define EM_D30V 86 /* Mitsubishi D30V. */
#define EM_V850 87 /* NEC v850. */
#define EM_M32R 88 /* Mitsubishi M32R. */
#define EM_MN10300 89 /* Matsushita MN10300. */
#define EM_MN10200 90 /* Matsushita MN10200. */
#define EM_PJ 91 /* picoJava. */
#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */
#define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */
#define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */
#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */
#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose
Processor. */
#define EM_NS32K 97 /* National Semiconductor 32000 series. */
#define EM_TPC 98 /* Tenor Network TPC processor. */
#define EM_SNP1K 99 /* Trebia SNP 1000 processor. */
#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */
#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */
#define EM_MAX 102 /* MAX Processor. */
#define EM_CR 103 /* National Semiconductor CompactRISC
microprocessor. */
#define EM_F2MC16 104 /* Fujitsu F2MC16. */
#define EM_MSP430 105 /* Texas Instruments embedded microcontroller
msp430. */
#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */
#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */
#define EM_SEP 108 /* Sharp embedded microprocessor. */
#define EM_ARCA 109 /* Arca RISC Microprocessor. */
#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd.
and MPRC of Peking University */

/* Non-standard or deprecated. */
#define EM_486 6 /* Intel i486. */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */

/* Special section indexes. */
#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
#define SHN_LORESERVE 0xff00 /* First of reserved range. */
#define SHN_LOPROC 0xff00 /* First processor-specific. */
#define SHN_HIPROC 0xff1f /* Last processor-specific. */
#define SHN_LOOS 0xff20 /* First operating system-specific. */
#define SHN_HIOS 0xff3f /* Last operating system-specific. */
#define SHN_ABS 0xfff1 /* Absolute values. */
#define SHN_COMMON 0xfff2 /* Common data. */
#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
#define SHN_HIRESERVE 0xffff /* Last of reserved range. */

/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends */
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relocation section - no addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
#define SHT_GROUP 17 /* Section group. */
#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
#define SHT_LOSUNW 0x6ffffff4
#define SHT_SUNW_dof 0x6ffffff4
#define SHT_SUNW_cap 0x6ffffff5
#define SHT_SUNW_SIGNATURE 0x6ffffff6
#define SHT_GNU_HASH 0x6ffffff6
#define SHT_SUNW_ANNOTATE 0x6ffffff7
#define SHT_SUNW_DEBUGSTR 0x6ffffff8
#define SHT_SUNW_DEBUG 0x6ffffff9
#define SHT_SUNW_move 0x6ffffffa
#define SHT_SUNW_COMDAT 0x6ffffffb
#define SHT_SUNW_syminfo 0x6ffffffc
#define SHT_SUNW_verdef 0x6ffffffd
#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */
#define SHT_SUNW_verneed 0x6ffffffe
#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */
#define SHT_SUNW_versym 0x6fffffff
#define SHT_GNU_versym 0x6fffffff /* Symbol version table */
#define SHT_HISUNW 0x6fffffff
#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */
#define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */
#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking
pre-emption map. */
#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility
attributes. */
#define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */
#define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */
#define SHT_MIPS_REGINFO 0x70000006
#define SHT_MIPS_OPTIONS 0x7000000d
#define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */

/* Flags for sh_flags. */
#define SHF_WRITE 0x1 /* Section contains writable data. */
#define SHF_ALLOC 0x2 /* Section occupies memory. */
#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
#define SHF_MERGE 0x10 /* Section may be merged. */
#define SHF_STRINGS 0x20 /* Section contains strings. */
#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
#define SHF_GROUP 0x200 /* Member of section group. */
#define SHF_TLS 0x400 /* Section contains TLS data. */
#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */

/* Values for p_type. */
#define PT_NULL 0 /* Unused entry. */
#define PT_LOAD 1 /* Loadable segment. */
#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
#define PT_INTERP 3 /* Pathname of interpreter. */
#define PT_NOTE 4 /* Auxiliary information. */
#define PT_SHLIB 5 /* Reserved (not used). */
#define PT_PHDR 6 /* Location of program header itself. */
#define PT_TLS 7 /* Thread local storage segment */
#define PT_LOOS 0x60000000 /* First OS-specific. */
#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
#define PT_GNU_EH_FRAME 0x6474e550
#define PT_GNU_STACK 0x6474e551
#define PT_GNU_RELRO 0x6474e552
#define PT_LOSUNW 0x6ffffffa
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
#define PT_SUNWDTRACE 0x6ffffffc /* private */
#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */
#define PT_HISUNW 0x6fffffff
#define PT_HIOS 0x6fffffff /* Last OS-specific. */
#define PT_LOPROC 0x70000000 /* First processor-specific type. */
#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */

/* Values for p_flags. */
#define PF_X 0x1 /* Executable. */
#define PF_W 0x2 /* Writable. */
#define PF_R 0x4 /* Readable. */
#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
#define PF_MASKPROC 0xf0000000 /* Processor-specific. */

/* Extended program header index. */
#define PN_XNUM 0xffff

/* Values for d_tag. */
#define DT_NULL 0 /* Terminating entry. */
#define DT_NEEDED 1 /* String table offset of a needed shared
library. */
#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
#define DT_PLTGOT 3 /* Processor-dependent address. */
#define DT_HASH 4 /* Address of symbol hash table. */
#define DT_STRTAB 5 /* Address of string table. */
#define DT_SYMTAB 6 /* Address of symbol table. */
#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
#define DT_STRSZ 10 /* Size of string table. */
#define DT_SYMENT 11 /* Size of each symbol table entry. */
#define DT_INIT 12 /* Address of initialization function. */
#define DT_FINI 13 /* Address of finalization function. */
#define DT_SONAME 14 /* String table offset of shared object
name. */
#define DT_RPATH 15 /* String table offset of library path. [sup] */
#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
#define DT_PLTREL 20 /* Type of relocation used for PLT. */
#define DT_DEBUG 21 /* Reserved (not used). */
#define DT_TEXTREL 22 /* Indicates there may be relocations in
non-writable segments. [sup] */
#define DT_JMPREL 23 /* Address of PLT relocations. */
#define DT_BIND_NOW 24 /* [sup] */
#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
initialization functions */
#define DT_FINI_ARRAY 26 /* Address of the array of pointers to
termination functions */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of
initialization functions. */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of
termination functions. */
#define DT_RUNPATH 29 /* String table offset of a null-terminated
library search path string. */
#define DT_FLAGS 30 /* Object specific flag values. */
#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING
and less than DT_LOOS follow the rules for
the interpretation of the d_un union
as follows: even == 'd_ptr', odd == 'd_val'
or none */
#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to
pre-initialization functions. */
#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of
pre-initialization functions. */
#define DT_MAXPOSTAGS 34 /* number of positive tags */
#define DT_LOOS 0x6000000d /* First OS-specific */
#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */
#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */
#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */
#define DT_SUNW_CAP 0x60000010 /* hardware/software */
#define DT_HIOS 0x6ffff000 /* Last OS-specific */

/*
* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
* Dyn.d_un.d_val field of the Elf*_Dyn structure.
*/
#define DT_VALRNGLO 0x6ffffd00
#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */
#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */
#define DT_MOVEENT 0x6ffffdfa /* move table entry size */
#define DT_MOVESZ 0x6ffffdfb /* move table size */
#define DT_FEATURE_1 0x6ffffdfc /* feature holder */
#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */
/* the following DT_* entry. */
/* See DF_P1_* definitions */
#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */
#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */
#define DT_VALRNGHI 0x6ffffdff

/*
* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
* Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
*
* If any adjustment is made to the ELF object after it has been
* built, these entries will need to be adjusted.
*/
#define DT_ADDRRNGLO 0x6ffffe00
#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */
#define DT_CONFIG 0x6ffffefa /* configuration information */
#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */
#define DT_AUDIT 0x6ffffefc /* object auditing */
#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */
#define DT_MOVETAB 0x6ffffefe /* move table */
#define DT_SYMINFO 0x6ffffeff /* syminfo table */
#define DT_ADDRRNGHI 0x6ffffeff

#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */
#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */
#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */
#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */
#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */
#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */
#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */
#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */

#define DT_LOPROC 0x70000000 /* First processor-specific type. */
#define DT_DEPRECATED_SPARC_REGISTER 0x7000001
#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */
#define DT_USED 0x7ffffffe /* ignored - same as needed */
#define DT_FILTER 0x7fffffff /* shared library filter name */
#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */

/* Values for DT_FLAGS */
#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may
make reference to the $ORIGIN substitution
string */
#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */
#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in
non-writable segments. */
#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should
process all relocations for the object
containing this entry before transferring
control to the program. */
#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or
executable contains code using a static
thread-local storage scheme. */

/* Values for DT_FLAGS_1 */
#define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */
#define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */
#define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */
#define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filtees */
#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */
#define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */
#define DF_1_INTERPOSE 0x00000400 /* Interpose all objects but main */
#define DF_1_NODEFLIB 0x00000800 /* Do not search default paths */

/* Values for n_type. Used in core files. */
#define NT_PRSTATUS 1 /* Process status. */
#define NT_FPREGSET 2 /* Floating point registers. */
#define NT_PRPSINFO 3 /* Process state info. */
#define NT_THRMISC 7 /* Thread miscellaneous info. */
#define NT_PROCSTAT_PROC 8 /* Procstat proc data. */
#define NT_PROCSTAT_FILES 9 /* Procstat files data. */
#define NT_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */
#define NT_PROCSTAT_GROUPS 11 /* Procstat groups data. */
#define NT_PROCSTAT_UMASK 12 /* Procstat umask data. */
#define NT_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */
#define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */
#define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */
#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */

/* Symbol Binding - ELFNN_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_LOOS 10 /* Reserved range for operating system */
#define STB_HIOS 12 /* specific semantics. */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific semantics. */

/* Symbol type - ELFNN_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* Unspecified type. */
#define STT_OBJECT 1 /* Data object. */
#define STT_FUNC 2 /* Function. */
#define STT_SECTION 3 /* Section. */
#define STT_FILE 4 /* Source file. */
#define STT_COMMON 5 /* Uninitialized common block. */
#define STT_TLS 6 /* TLS object. */
#define STT_NUM 7
#define STT_LOOS 10 /* Reserved range for operating system */
#define STT_GNU_IFUNC 10
#define STT_HIOS 12 /* specific semantics. */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific semantics. */

/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
#define STV_HIDDEN 0x2 /* Not visible. */
#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
#define STV_EXPORTED 0x4
#define STV_SINGLETON 0x5
#define STV_ELIMINATE 0x6

/* Special symbol table indexes. */
#define STN_UNDEF 0 /* Undefined symbol index. */

/* Symbol versioning flags. */
#define VER_DEF_CURRENT 1
#define VER_DEF_IDX(x) VER_NDX(x)

#define VER_FLG_BASE 0x01
#define VER_FLG_WEAK 0x02

#define VER_NEED_CURRENT 1
#define VER_NEED_WEAK (1u << 15)
#define VER_NEED_HIDDEN VER_NDX_HIDDEN
#define VER_NEED_IDX(x) VER_NDX(x)

#define VER_NDX_LOCAL 0
#define VER_NDX_GLOBAL 1
#define VER_NDX_GIVEN 2

#define VER_NDX_HIDDEN (1u << 15)
#define VER_NDX(x) ((x) & ~(1u << 15))

#define CA_SUNW_NULL 0
#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */
#define CA_SUNW_SF_1 2 /* first software capabilities entry */

/*
* Syminfo flag values
*/
#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */
/* to object containing defn. */
#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */
#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */
#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */
/* lazily-loaded */
#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */
/* object containing defn. */
#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */
/* directly bind to this symbol */
#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */
#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */

/*
* Syminfo.si_boundto values.
*/
#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */
#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */
#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */
#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */
#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */

/*
* Syminfo version values.
*/
#define SYMINFO_NONE 0 /* Syminfo version */
#define SYMINFO_CURRENT 1
#define SYMINFO_NUM 2

/*
* Relocation types.
*
* All machine architectures are defined here to allow tools on one to
* handle others.
*/

#define R_386_NONE 0 /* No relocation. */
#define R_386_32 1 /* Add symbol value. */
#define R_386_PC32 2 /* Add PC-relative symbol value. */
#define R_386_GOT32 3 /* Add PC-relative GOT offset. */
#define R_386_PLT32 4 /* Add PC-relative PLT offset. */
#define R_386_COPY 5 /* Copy data from shared object. */
#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */
#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */
#define R_386_RELATIVE 8 /* Add load address of shared object. */
#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */
#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */
#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */
#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */
#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */
#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */
#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */
#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */
#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */
#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */
#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */
#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */
#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */
#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */
#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */
#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */
#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */
#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */
#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */
#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */
#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */
#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */
#define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */

#define R_ARM_NONE 0 /* No relocation. */
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_ARM_REL32 3
#define R_ARM_PC13 4
#define R_ARM_ABS16 5
#define R_ARM_ABS12 6
#define R_ARM_THM_ABS5 7
#define R_ARM_ABS8 8
#define R_ARM_SBREL32 9
#define R_ARM_THM_PC22 10
#define R_ARM_THM_PC8 11
#define R_ARM_AMP_VCALL9 12
#define R_ARM_SWI24 13
#define R_ARM_THM_SWI8 14
#define R_ARM_XPC25 15
#define R_ARM_THM_XPC22 16
/* TLS relocations */
#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
#define R_ARM_COPY 20 /* Copy data from shared object. */
#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */
#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */
#define R_ARM_RELATIVE 23 /* Add load address of shared object. */
#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */
#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */
#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */
#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */
#define R_ARM_GNU_VTENTRY 100
#define R_ARM_GNU_VTINHERIT 101
#define R_ARM_RSBREL32 250
#define R_ARM_THM_RPC22 251
#define R_ARM_RREL32 252
#define R_ARM_RABS32 253
#define R_ARM_RPC24 254
#define R_ARM_RBASE 255

/* Name Value Field Calculation */
#define R_IA_64_NONE 0 /* None */
#define R_IA_64_IMM14 0x21 /* immediate14 S + A */
#define R_IA_64_IMM22 0x22 /* immediate22 S + A */
#define R_IA_64_IMM64 0x23 /* immediate64 S + A */
#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */
#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */
#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */
#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */
#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */
#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */
#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */
#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */
#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */
#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */
#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */
#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */
#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */
#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */
#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */
#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */
#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */
#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */
#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */
#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */
#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */
#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */
#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */
#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */
#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */
#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */
#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */
#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */
#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */
#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */
#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */
#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */
#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */
#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */
#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */
#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */
#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */
#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */
#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */
#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */
#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */
#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */
#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */
#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */
#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */
#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */
#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */
#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */
#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */
#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */
#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */
#define R_IA_64_SUB 0x85 /* immediate64 A - S */
#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */
#define R_IA_64_LDXMOV 0x87 /* immediate22 special */
#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */
#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */
#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */
#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */
#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */
#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */
#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */
#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */
#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */
#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */
#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */
#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */
#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */
#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */
#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */
#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */
#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */

#define R_MIPS_NONE 0 /* No reloc */
#define R_MIPS_16 1 /* Direct 16 bit */
#define R_MIPS_32 2 /* Direct 32 bit */
#define R_MIPS_REL32 3 /* PC relative 32 bit */
#define R_MIPS_26 4 /* Direct 26 bit shifted */
#define R_MIPS_HI16 5 /* High 16 bit */
#define R_MIPS_LO16 6 /* Low 16 bit */
#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
#define R_MIPS_PC16 10 /* PC relative 16 bit */
#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
#define R_MIPS_GOTHI16 21 /* GOT HI 16 bit */
#define R_MIPS_GOTLO16 22 /* GOT LO 16 bit */
#define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */
#define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */

#define R_PPC_NONE 0 /* No relocation. */
#define R_PPC_ADDR32 1
#define R_PPC_ADDR24 2
#define R_PPC_ADDR16 3
#define R_PPC_ADDR16_LO 4
#define R_PPC_ADDR16_HI 5
#define R_PPC_ADDR16_HA 6
#define R_PPC_ADDR14 7
#define R_PPC_ADDR14_BRTAKEN 8
#define R_PPC_ADDR14_BRNTAKEN 9
#define R_PPC_REL24 10
#define R_PPC_REL14 11
#define R_PPC_REL14_BRTAKEN 12
#define R_PPC_REL14_BRNTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLTREL24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_UADDR32 24
#define R_PPC_UADDR16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36

/*
* 64-bit relocations
*/
#define R_PPC64_ADDR64 38
#define R_PPC64_ADDR16_HIGHER 39
#define R_PPC64_ADDR16_HIGHERA 40
#define R_PPC64_ADDR16_HIGHEST 41
#define R_PPC64_ADDR16_HIGHESTA 42
#define R_PPC64_UADDR64 43
#define R_PPC64_REL64 44
#define R_PPC64_PLT64 45
#define R_PPC64_PLTREL64 46
#define R_PPC64_TOC16 47
#define R_PPC64_TOC16_LO 48
#define R_PPC64_TOC16_HI 49
#define R_PPC64_TOC16_HA 50
#define R_PPC64_TOC 51
#define R_PPC64_DTPMOD64 68
#define R_PPC64_TPREL64 73
#define R_PPC64_DTPREL64 78

/*
* TLS relocations
*/
#define R_PPC_TLS 67
#define R_PPC_DTPMOD32 68
#define R_PPC_TPREL16 69
#define R_PPC_TPREL16_LO 70
#define R_PPC_TPREL16_HI 71
#define R_PPC_TPREL16_HA 72
#define R_PPC_TPREL32 73
#define R_PPC_DTPREL16 74
#define R_PPC_DTPREL16_LO 75
#define R_PPC_DTPREL16_HI 76
#define R_PPC_DTPREL16_HA 77
#define R_PPC_DTPREL32 78
#define R_PPC_GOT_TLSGD16 79
#define R_PPC_GOT_TLSGD16_LO 80
#define R_PPC_GOT_TLSGD16_HI 81
#define R_PPC_GOT_TLSGD16_HA 82
#define R_PPC_GOT_TLSLD16 83
#define R_PPC_GOT_TLSLD16_LO 84
#define R_PPC_GOT_TLSLD16_HI 85
#define R_PPC_GOT_TLSLD16_HA 86
#define R_PPC_GOT_TPREL16 87
#define R_PPC_GOT_TPREL16_LO 88
#define R_PPC_GOT_TPREL16_HI 89
#define R_PPC_GOT_TPREL16_HA 90

/*
* The remaining relocs are from the Embedded ELF ABI, and are not in the
* SVR4 ELF ABI.
*/

#define R_PPC_EMB_NADDR32 101
#define R_PPC_EMB_NADDR16 102
#define R_PPC_EMB_NADDR16_LO 103
#define R_PPC_EMB_NADDR16_HI 104
#define R_PPC_EMB_NADDR16_HA 105
#define R_PPC_EMB_SDAI16 106
#define R_PPC_EMB_SDA2I16 107
#define R_PPC_EMB_SDA2REL 108
#define R_PPC_EMB_SDA21 109
#define R_PPC_EMB_MRKREF 110
#define R_PPC_EMB_RELSEC16 111
#define R_PPC_EMB_RELST_LO 112
#define R_PPC_EMB_RELST_HI 113
#define R_PPC_EMB_RELST_HA 114
#define R_PPC_EMB_BIT_FLD 115
#define R_PPC_EMB_RELSDA 116

#define R_SPARC_NONE 0
#define R_SPARC_8 1
#define R_SPARC_16 2
#define R_SPARC_32 3
#define R_SPARC_DISP8 4
#define R_SPARC_DISP16 5
#define R_SPARC_DISP32 6
#define R_SPARC_WDISP30 7
#define R_SPARC_WDISP22 8
#define R_SPARC_HI22 9
#define R_SPARC_22 10
#define R_SPARC_13 11
#define R_SPARC_LO10 12
#define R_SPARC_GOT10 13
#define R_SPARC_GOT13 14
#define R_SPARC_GOT22 15
#define R_SPARC_PC10 16
#define R_SPARC_PC22 17
#define R_SPARC_WPLT30 18
#define R_SPARC_COPY 19
#define R_SPARC_GLOB_DAT 20
#define R_SPARC_JMP_SLOT 21
#define R_SPARC_RELATIVE 22
#define R_SPARC_UA32 23
#define R_SPARC_PLT32 24
#define R_SPARC_HIPLT22 25
#define R_SPARC_LOPLT10 26
#define R_SPARC_PCPLT32 27
#define R_SPARC_PCPLT22 28
#define R_SPARC_PCPLT10 29
#define R_SPARC_10 30
#define R_SPARC_11 31
#define R_SPARC_64 32
#define R_SPARC_OLO10 33
#define R_SPARC_HH22 34
#define R_SPARC_HM10 35
#define R_SPARC_LM22 36
#define R_SPARC_PC_HH22 37
#define R_SPARC_PC_HM10 38
#define R_SPARC_PC_LM22 39
#define R_SPARC_WDISP16 40
#define R_SPARC_WDISP19 41
#define R_SPARC_GLOB_JMP 42
#define R_SPARC_7 43
#define R_SPARC_5 44
#define R_SPARC_6 45
#define R_SPARC_DISP64 46
#define R_SPARC_PLT64 47
#define R_SPARC_HIX22 48
#define R_SPARC_LOX10 49
#define R_SPARC_H44 50
#define R_SPARC_M44 51
#define R_SPARC_L44 52
#define R_SPARC_REGISTER 53
#define R_SPARC_UA64 54
#define R_SPARC_UA16 55
#define R_SPARC_TLS_GD_HI22 56
#define R_SPARC_TLS_GD_LO10 57
#define R_SPARC_TLS_GD_ADD 58
#define R_SPARC_TLS_GD_CALL 59
#define R_SPARC_TLS_LDM_HI22 60
#define R_SPARC_TLS_LDM_LO10 61
#define R_SPARC_TLS_LDM_ADD 62
#define R_SPARC_TLS_LDM_CALL 63
#define R_SPARC_TLS_LDO_HIX22 64
#define R_SPARC_TLS_LDO_LOX10 65
#define R_SPARC_TLS_LDO_ADD 66
#define R_SPARC_TLS_IE_HI22 67
#define R_SPARC_TLS_IE_LO10 68
#define R_SPARC_TLS_IE_LD 69
#define R_SPARC_TLS_IE_LDX 70
#define R_SPARC_TLS_IE_ADD 71
#define R_SPARC_TLS_LE_HIX22 72
#define R_SPARC_TLS_LE_LOX10 73
#define R_SPARC_TLS_DTPMOD32 74
#define R_SPARC_TLS_DTPMOD64 75
#define R_SPARC_TLS_DTPOFF32 76
#define R_SPARC_TLS_DTPOFF64 77
#define R_SPARC_TLS_TPOFF32 78
#define R_SPARC_TLS_TPOFF64 79

#define R_X86_64_NONE 0 /* No relocation. */
#define R_X86_64_64 1 /* Add 64 bit symbol value. */
#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */
#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */
#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */
#define R_X86_64_COPY 5 /* Copy data from shared object. */
#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */
#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */
#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */
#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */
#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */
#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */
#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */
#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */
#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */
#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */
#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */
#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */
#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */
#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */
#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */
#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */
#define R_X86_64_IRELATIVE 37


#endif /* !_SYS_ELF_COMMON_H_ */

@ -11,11 +11,14 @@
#include "io.h"
#include "sdram.h"
#include "console.h"
#include "elf64.h"

#define FLASH_LOADER_USE_MAP

int _printf(const char *fmt, ...)
{
int count;
char buffer[320];
char buffer[128];
va_list ap;

va_start(ap, fmt);
@ -34,9 +37,208 @@ void flush_cpu_icache(void)
__asm__ volatile ("icbi 0,0; isync" : : : "memory");
}

void main(void)
#define SPI_CMD_RDID 0x9f
#define SPI_CMD_READ 0x03
#define SPI_CMD_DUAL_FREAD 0x3b
#define SPI_CMD_QUAD_FREAD 0x6b
#define SPI_CMD_RDCR 0x35
#define SPI_CMD_WREN 0x06
#define SPI_CMD_PP 0x02
#define SPI_CMD_RDSR 0x05
#define SPI_CMD_WWR 0x01

static void fl_cs_on(void)
{
writeb(SPI_REG_CTRL_MANUAL_CS, SPI_FCTRL_BASE + SPI_REG_CTRL);
}

static void fl_cs_off(void)
{
writeb(0, SPI_FCTRL_BASE + SPI_REG_CTRL);
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("nop");
}

static void wait_wip(void)
{
for (;;) {
uint8_t sr;

fl_cs_on();
writeb(SPI_CMD_RDSR, SPI_FCTRL_BASE + SPI_REG_DATA);
sr = readb(SPI_FCTRL_BASE + SPI_REG_DATA);
fl_cs_off();
if ((sr & 1) == 0)
break;
}
}

static void send_wren(void)
{
fl_cs_on();
writeb(SPI_CMD_WREN, SPI_FCTRL_BASE + SPI_REG_DATA);
fl_cs_off();
}

static void check_spansion_quad_mode(void)
{
uint8_t cf1;

writeb(SPI_CMD_RDCR, SPI_FCTRL_BASE + SPI_REG_DATA);
fl_cs_on();
writeb(SPI_CMD_RDCR, SPI_FCTRL_BASE + SPI_REG_DATA);
cf1 = readb(SPI_FCTRL_BASE + SPI_REG_DATA);
fl_cs_off();
printf(" Cypress/Spansion (CF1=%02x)", cf1);
if (cf1 & 0x02)
return;
printf(" enabling QUAD");
send_wren();
fl_cs_on();
writeb(SPI_CMD_WWR, SPI_FCTRL_BASE + SPI_REG_DATA);
writeb(0x00, SPI_FCTRL_BASE + SPI_REG_DATA);
writeb(cf1 | 0x02, SPI_FCTRL_BASE + SPI_REG_DATA);
writeb(0, SPI_FCTRL_BASE + SPI_REG_CTRL);
fl_cs_off();
wait_wip();
}

static bool check_flash(void)
{
bool quad = false;
uint8_t id[3];

fl_cs_on();
writeb(SPI_CMD_RDID, SPI_FCTRL_BASE + SPI_REG_DATA);
id[0] = readb(SPI_FCTRL_BASE + SPI_REG_DATA);
id[1] = readb(SPI_FCTRL_BASE + SPI_REG_DATA);
id[2] = readb(SPI_FCTRL_BASE + SPI_REG_DATA);
fl_cs_off();
printf(" SPI FLASH ID: %02x%02x%02x", id[0], id[1], id[2]);

if ((id[0] | id[1] | id[2]) == 0 ||
(id[0] & id[1] & id[2]) == 0xff)
return false;

/* Supported flash types for quad mode */
if (id[0] == 0x01 &&
(id[1] == 0x02 || id[1] == 0x20) &&
(id[2] == 0x18 || id[2] == 0x19)) {
check_spansion_quad_mode();
quad = true;
}
if (id[0] == 0x20 && id[1] == 0xba && id[2] == 0x18) {
printf(" Micron");
quad = true;
}
if (quad) {
uint32_t cfg;
printf(" [quad IO mode]");

/* Preserve the default clock div for the board */
cfg = readl(SPI_FCTRL_BASE + SPI_REG_AUTO_CFG);
cfg &= SPI_REG_AUTO_CFG_CKDIV_MASK;

/* Enable quad mode, 8 dummy clocks, 32 cycles CS timeout */
cfg |= SPI_CMD_QUAD_FREAD |
(0x07 << SPI_REG_AUTO_CFG_DUMMIES_SHIFT) |
SPI_REG_AUT_CFG_MODE_QUAD |
(0x20 << SPI_REG_AUTO_CFG_CSTOUT_SHIFT);
writel(cfg, SPI_FCTRL_BASE + SPI_REG_AUTO_CFG);
}
printf("\n");

return true;
}

static bool fl_read(void *dst, uint32_t offset, uint32_t size)
{
unsigned long long ftr, val;
uint8_t *d = dst;

#ifdef FLASH_LOADER_USE_MAP
memcpy(d, (void *)(unsigned long)(SPI_FLASH_BASE + offset), size);
#else
if (size < 1)
return false;
fl_cs_on();
writeb(SPI_CMD_QUAD_FREAD, SPI_FCTRL_BASE + SPI_REG_DATA);
writeb(offset >> 16, SPI_FCTRL_BASE + SPI_REG_DATA);
writeb(offset >> 8, SPI_FCTRL_BASE + SPI_REG_DATA);
writeb(offset, SPI_FCTRL_BASE + SPI_REG_DATA);
writeb(0x00, SPI_FCTRL_BASE + SPI_REG_DATA);
while(size--)
*(d++) = readb(SPI_FCTRL_BASE + SPI_REG_DATA_QUAD);
fl_cs_off();
#endif

return true;
}

static unsigned long boot_flash(unsigned int offset)
{
Elf64_Ehdr ehdr;
Elf64_Phdr ph;
unsigned int i, poff, size, off;
void *addr;

printf("Trying flash...\n");
if (!fl_read(&ehdr, offset, sizeof(ehdr)))
return -1ul;
if (!IS_ELF(ehdr) || ehdr.e_ident[EI_CLASS] != ELFCLASS64) {
printf("Doesn't look like an elf64\n");
goto dump;
}
if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB ||
ehdr.e_machine != EM_PPC64) {
printf("Not a ppc64le binary\n");
goto dump;
}

poff = offset + ehdr.e_phoff;
for (i = 0; i < ehdr.e_phnum; i++) {
if (!fl_read(&ph, poff, sizeof(ph)))
goto dump;
if (ph.p_type != PT_LOAD)
continue;

/* XXX Add bound checking ! */
size = ph.p_filesz;
addr = (void *)ph.p_vaddr;
off = offset + ph.p_offset;
printf("Copy segment %d (0x%x bytes) to %p\n", i, size, addr);
fl_read(addr, off, size);
poff += ehdr.e_phentsize;
}

printf("Booting from DRAM at %x\n", (unsigned int)ehdr.e_entry);
flush_cpu_icache();
return ehdr.e_entry;
dump:
printf("HDR: %02x %02x %02x %02x %02x %02x %02x %02x\n",
ehdr.e_ident[0], ehdr.e_ident[1], ehdr.e_ident[2], ehdr.e_ident[3],
ehdr.e_ident[4], ehdr.e_ident[5], ehdr.e_ident[6], ehdr.e_ident[7]);
return -1ul;
}

static void boot_sdram(void)
{
void *s = (void *)(DRAM_INIT_BASE + 0x4000);
void *d = (void *)DRAM_BASE;
int sz = (0x10000 - 0x4000);
printf("Copying payload to DRAM...\n");
memcpy(d, s, sz);
printf("Booting from DRAM...\n");
flush_cpu_icache();
}

uint64_t main(void)
{
unsigned long ftr, val;
unsigned int fl_off = 0;
bool try_flash = false;

/* Init the UART */
potato_uart_init();
@ -56,35 +258,43 @@ void main(void)
printf("DRAM ");
if (ftr & SYS_REG_INFO_HAS_BRAM)
printf("BRAM ");
if (ftr & SYS_REG_INFO_HAS_SPI_FLASH)
printf("SPIFLASH ");
printf("\n");
if (ftr & SYS_REG_INFO_HAS_BRAM) {
val = readq(SYSCON_BASE + SYS_REG_BRAMINFO) & SYS_REG_BRAMINFO_SIZE_MASK;
printf(" BRAM: %lld KB\n", val / 1024);
printf(" BRAM: %ld KB\n", val / 1024);
}
if (ftr & SYS_REG_INFO_HAS_DRAM) {
val = readq(SYSCON_BASE + SYS_REG_DRAMINFO) & SYS_REG_DRAMINFO_SIZE_MASK;
printf(" DRAM: %lld MB\n", val / (1024 * 1024));
printf(" DRAM: %ld MB\n", val / (1024 * 1024));
val = readq(SYSCON_BASE + SYS_REG_DRAMINITINFO);
printf(" DRAM INIT: %lld KB\n", val / 1024);
printf(" DRAM INIT: %ld KB\n", val / 1024);
}
val = readq(SYSCON_BASE + SYS_REG_CLKINFO) & SYS_REG_CLKINFO_FREQ_MASK;
printf(" CLK: %lld MHz\n", val / 1000000);

printf(" CLK: %ld MHz\n", val / 1000000);
if (ftr & SYS_REG_INFO_HAS_SPI_FLASH) {
val = readq(SYSCON_BASE + SYS_REG_SPI_INFO);
try_flash = check_flash();
fl_off = val & SYS_REG_SPI_INFO_FLASH_OFF_MASK;
printf(" SPI FLASH OFF: 0x%x bytes\n", fl_off);
try_flash = true;
}
printf("\n");
if (ftr & SYS_REG_INFO_HAS_DRAM) {
printf("LiteDRAM built from Migen %s and LiteX %s\n",
MIGEN_GIT_SHA1, LITEX_GIT_SHA1);
sdrinit();
}
if (ftr & SYS_REG_INFO_HAS_BRAM)
if (ftr & SYS_REG_INFO_HAS_BRAM) {
printf("Booting from BRAM...\n");
else {
void *s = (void *)(DRAM_INIT_BASE + 0x4000);
void *d = (void *)DRAM_BASE;
int sz = (0x10000 - 0x4000);
printf("Copying payload to DRAM...\n");
memcpy(d, s, sz);
printf("Booting from DRAM...\n");
flush_cpu_icache();
return 0;
}
if (try_flash) {
val = boot_flash(fl_off);
if (val != (unsigned long)-1)
return val;
}
boot_sdram();
return 0;
}

@ -4,12 +4,12 @@ a602487d05009f42
a64b5a7d14004a39
2402004ca64b7b7d
602100003c200000
6421f000782107c6
6421ff00782107c6
3d80000060213f00
798c07c6618c0000
618c10a4658cf000
618c10e0658cff00
4e8004217d8903a6
0000000048000002
4e8004207c6903a6
0000000000000000
0000000000000000
0000000000000000
@ -510,93 +510,220 @@ a64b5a7d14004a39
0000000000000000
0000000000000000
0000000000000000
3842a1003c4c0001
fbc1fff07c0802a6
f8010010fbe1fff8
3be10020f821fe91
f8a101a0f8810198
f8c101a838800140
38c101987c651b78
7fe3fb78f8e101b0
f92101c0f90101b8
48001735f94101c8
7c7e1b7860000000
4800124d7fe3fb78
3821017060000000
48001cf47fc3f378
0100000000000000
4e80002000000280
0000000000000000
7c0007ac00000000
4e8000204c00012c
392000003d40c000
794a0020614a6004
7d2057aa7c0004ac
6000000060000000
6000000060000000
4e80002060000000
0000000000000000
3c4c000100000000
7c0802a63842a05c
7d800026fbe1fff8
91810008f8010010
48001141f821ff91
7c0802a63842a5c4
fbe1fff8fbc1fff0
f821ff51f8010010
f88100d83be10020
38800080f8a100e0
7c651b78f8c100e8
f8e100f038c100d8
f90100f87fe3fb78
f9410108f9210100
6000000048001af9
7fe3fb787c7e1b78
6000000048001611
7fc3f378382100b0
00000000480020b8
0000028001000000
000000004e800020
0000000000000000
4c00012c7c0007ac
000000004e800020
0000000000000000
3842a5203c4c0001
7d8000267c0802a6
9181000848001ff5
48001505f821fed1
3c62ffff60000000
4bffff3538637c78
4bffff3938637b78
548400023880ffff
7c8026ea7c0004ac
3fe0c0003c62ffff
63ff000838637c98
3c62ffff4bffff11
38637cb87bff0020
7c0004ac4bffff01
63ff000838637b98
3c62ffff4bffff15
38637bb87bff0020
7c0004ac4bffff05
73e900017fe0feea
3c62ffff41820010
4bfffee538637cd0
4d80000073e90002
4bfffee938637bd0
4e00000073e90002
3c62ffff41820010
4bfffecd38637cd8
4e00000073e90004
4bfffed138637bd8
4d80000073e90004
3c62ffff41820010
4bfffeb538637ce0
3bff7f203fe2ffff
4bfffea57fe3fb78
3c80c00041920028
4bfffeb938637be0
4d00000073e90008
3c62ffff41820010
4bfffea138637be8
3b7b7f683f62ffff
4bfffe917f63db78
3c80c000418e0028
7884002060840010
7c8026ea7c0004ac
7884b2823c62ffff
4bfffe7d38637ce8
3c80c000418e004c
7884b5823c62ffff
4bfffe6938637bf8
3c80c0004192004c
7884002060840018
7c8026ea7c0004ac
788465023c62ffff
4bfffe5538637d08
788460223c62ffff
4bfffe4138637c10
608400303c80c000
7c0004ac78840020
3c62ffff7c8026ea
38637d287884b282
3d20c0004bfffe31
38637c287884b282
3d20c0004bfffe1d
7929002061290020
7d204eea7c0004ac
3c62ffff3c80000f
38637d4860844240
4bfffe057c892392
4bfffdfd7fe3fb78
3ca2ffff418e0028
3c62ffff3c82ffff
38847d7838a57d68
4bfffddd38637d80
6000000048000e29
3c62ffff41920020
4bfffdc538637db0
8181000838210070
48001b107d818120
38637dc83c62ffff
3c80f0004bfffda9
792906003c80000f
3c62ffff60844240
38637c407c892392
418a02584bfffded
63bd00383fa0c000
7c0004ac7bbd0020
3d40c0007fa0eeea
614a600439200002
7c0004ac794a0020
3fe0c0007d2057aa
63ff60003920ff9f
7c0004ac7bff0020
7c0004ac7d20ffaa
579c063e7f80feaa
7fc0feaa7c0004ac
7c0004ac57de063e
4bfffd3d7fe0feaa
3c62ffff57ff063e
7fc5f3787fe6fb78
38637c607f84e378
7f89f3784bfffd65
2f8900007d29fb78
7f89f038419e0164
2f8900ff7d29f838
2b9c0001419e0154
2b9e0002409e0374
2b9e0020419e000c
3bffffe8409e0134
2b9f000157ff063e
3fe0c000419d0124
63ff600039200035
7c0004ac7bff0020
3fc0c0007d20ffaa
63de60043b400002
7c0004ac7bde0020
7c0004ac7f40f7aa
7c0004ac7d20ffaa
4bfffc957f80feaa
3c62ffff579c063e
38637c807f84e378
738900024bfffcc5
3c62ffff40820090
4bfffcb138637ca0
7f40f7aa7c0004ac
7c0004ac39200006
4bfffc557d20ffaa
7f40f7aa7c0004ac
7c0004ac39200001
392000007d20ffaa
7d20ffaa7c0004ac
7c0004ac639c0002
7c0004ac7f80ffaa
4bfffc1d7d20f7aa
3b4000053b200002
7f20f7aa7c0004ac
7f40ffaa7c0004ac
7f80feaa7c0004ac
4bfffbf5579c063e
4082ffdc73890001
38637cb83c62ffff
3d40c0004bfffc25
794a0020614a6008
7d20562a7c0004ac
652920005529021e
7c0004ac61291f6b
7f63db787d20572a
7bbd00204bfffbf5
7fa4eb783c62ffff
4bfffbe138637cc8
7f63db783be00001
419200284bfffbd5
3c82ffff3ca2ffff
38a57ce83c62ffff
38637d0038847cf8
48000fbd4bfffbb5
418e002460000000
38637d303c62ffff
386000004bfffb9d
3be0000048000144
4bffffb03ba00000
419e00842fbf0000
38637d483c62ffff
3c9df0004bfffb75
7884002038a00040
4800137d38610070
e921007060000000
614a464c3d400002
79290600794a83e4
7fa95000614a457f
3c62ffff419e0080
4bfffb3138637d60
8941007688610077
8901007489210075
88c1007288e10073
8881007088a10071
3c62fffff8610060
4bfffb0138637de0
38637e103c62ffff
3c80ff004bfffaf5
6084400038a0ffff
7884002054a50422
480011e53c604000
480012f53c604000
3c62ffff60000000
4bfffd7d38637de8
e801001038210070
ebe1fff881810008
7d8181207c0803a6
000000004bfffde4
0000018003000000
4bfffac938637e30
4bffff284bfffb49
2f89000189210075
a1210082409e0010
419e00102f890015
38637d803c62ffff
ebe100904bffff6c
3bc000003f02ffff
3b187d983b2100b0
7bff00207fffea14
7f89f040a12100a8
80810088419d0034
38637dc03c62ffff
4bfffae54bfffa65
2fa3ffffe8610088
38210130419eff58
7d83812081810008
3c9ff00048001b34
7884002038a00038
4800124d7f23cb78
812100b060000000
409e004c2f890001
eb6100c0eb4100d0
7fc4f378eb8100b8
7f66db787f03c378
3f9cf0007b450020
7c9de2144bfff9fd
788400207b450020
480012057f63db78
a12100a660000000
7bff00207fe9fa14
7bde00203bde0001
2b9c00204bffff50
2b9e00ba409efdcc
2b9f0018409efdc4
3c62ffff409efdbc
4bfff9a938637cb0
000000004bfffd78
0000088003000000
612908043d20c010
7c0004ac79290020
3d40c0107c604f2a
@ -653,11 +780,11 @@ ebe1fff881810008
9864000099240001
000000004e800020
0000000000000000
38429c883c4c0001
480018557c0802a6
38429d903c4c0001
4800185d7c0802a6
7c7e1b78f821ff21
38637eb83c62ffff
600000004bfffb71
38637f003c62ffff
600000004bfff7b5
390100603ca08020
3940000460a50003
7d1d43783920002a
@ -708,7 +835,7 @@ ebe1fff881810008
793500203ee2ffff
7d2907b47ed607b4
3b0100703be00000
7f3db2143af77ee0
7f3db2143af77f28
7f5d4a147ebdaa14
3860000f4bfffd75
4bfffca93b800000
@ -749,8 +876,8 @@ ebe1fff881810008
4bffffcc3b400000
7fbfe2142f9f0020
409e006c7fbd0e70
38637ec83c62ffff
600000004bfff889
38637f103c62ffff
600000004bfff4cd
3be000007fc3f378
7f9fe8004bfffb8d
3d40c010419c0070
@ -761,45 +888,45 @@ ebe1fff881810008
7d20572a7c0004ac
4bfffaed3860000b
4bfffb213860000f
4800154c382100e0
48001554382100e0
3c62ffff7cbfe050
7ca501947ca50e70
38637ed07fa4eb78
4bfff80d7ca507b4
38637f187fa4eb78
4bfff4517ca507b4
4bffff8460000000
3bff00017fc3f378
7fff07b44bfffb59
000000004bffff7c
00000b8001000000
384298d83c4c0001
384299e03c4c0001
3d40c0107c0802a6
3920000e614a0800
f8010010794a0020
7c0004acf821ffa1
3c62ffff7d20572a
4bfff7ad38637f90
4bfff3f138637fd0
3821006060000000
7c0803a6e8010010
000000004e800020
0000008001000000
384298803c4c0001
384299883c4c0001
3d40c0107c0802a6
39200001614a0800
f8010010794a0020
7c0004acf821ffa1
3c62ffff7d20572a
4bfff75538637f00
4bfff39938637f48
3821006060000000
7c0803a6e8010010
000000004e800020
0000008001000000
384298283c4c0001
384299303c4c0001
390000807c0802a6
3d40aaaa7d0903a6
614aaaaa3d204000
f821ff8148001401
f821ff8148001409
3929000491490000
4bfff7714200fff8
4bfff3b54200fff8
3940008060000000
7d4903a63d00aaaa
3be000003d204000
@ -811,7 +938,7 @@ f821ff8148001401
3d2040007d0903a6
91490000614a5555
4200fff839290004
600000004bfff715
600000004bfff359
3d00555539400080
3d2040007d4903a6
8149000061085555
@ -820,8 +947,8 @@ f821ff8148001401
4200ffe839290004
419e001c2fbf0000
38a001003c62ffff
38637e007fe4fb78
600000004bfff651
38637e487fe4fb78
600000004bfff295
3ce080203d000008
60e700037d0903a6
392000013d404000
@ -829,7 +956,7 @@ f821ff8148001401
7d2900d0792907e0
7d293838394a0004
912afffc7d294278
4bfff6814200ffe4
4bfff2c54200ffe4
3d00000860000000
7d0903a63ce08020
3d40400060e70003
@ -843,13 +970,13 @@ f821ff8148001401
2fbd00004200ffd4
3c62ffff419e001c
7fa4eb783ca00008
4bfff59d38637e28
4bfff1e138637e70
3920200060000000
7d2903a639400000
794800203d2a1000
394a000139290002
9109000079291764
4bfff5e14200ffe8
4bfff2254200ffe8
3920200060000000
7d2903a639400000
3d2a10003bc00000
@ -860,12 +987,12 @@ f821ff8148001401
2fbe00004200ffdc
3c62ffff419e001c
7fc4f37838a02000
4bfff51538637e50
4bfff15938637e98
7fffea1460000000
7ffff21438600000
409e00a42f9f0000
38637e783c62ffff
600000004bfff4f1
38637ec03c62ffff
600000004bfff135
3d4000047c9602a6
7d4903a678840020
3d49080039200000
@ -873,7 +1000,7 @@ f92a0000794a1f24
4200fff039290001
7c9f20507ff602a6
7fff23963fe06400
600000004bfff525
600000004bfff169
7d3602a67bff0020
792900203d000004
3d4040007d0903a6
@ -881,14 +1008,14 @@ f92a0000794a1f24
7cb602a64200fff8
3ca064007d254850
3c62ffff7ca54b96
38637e887fe4fb78
4bfff46578a50060
38637ed07fe4fb78
4bfff0a978a50060
3860000160000000
4800119438210080
4800119c38210080
0100000000000000
3c4c000100000380
7c0802a63842953c
f821fec1480010ed
7c0802a638429644
f821fec1480010f5
3bc000013fe0c010
7bff002063ff0014
386000004bfffc49
@ -903,15 +1030,15 @@ f821fec1480010ed
7fc0e72a7c0004ac
7fa0ff2a7c0004ac
3b8100703c62ffff
3e02ffff38637f40
600000004bfff3b9
3e02ffff38637f88
600000004bffeffd
fb8100803d22ffff
39297f503de2ffff
39297f983de2ffff
3e42ffff3dc2ffff
f92100983ae10063
3be000003ac10061
39ef7f603a107ee0
3a527f2039ce7f68
39ef7fa83a107f28
3a527f6839ce7fb0
3b20000139210064
3ea0c0103e80c010
39210068f9210088
@ -975,7 +1102,7 @@ e88100904bfff62d
e86100987f604f2a
7fe4fb787fa5eb78
3b6000003b400020
600000004bfff181
600000004bffedc5
4bfff4897fe3fb78
3860000f4bfff51d
4bfff4513a200001
@ -989,25 +1116,25 @@ f94100a0e8810080
394a0004409e0090
409effc02baa0010
7de37b787e248b78
600000004bfff111
600000004bffed55
7fe3fb783b5affff
7b5a00214bfff461
7f7b07b47f7b8a14
7dc373784082ff80
600000004bfff0e9
600000004bffed2d
7c0004ac39200000
7c0004ac7d20a72a
3860000b7d20af2a
3860000f4bfff379
7fe3fb784bfff3ad
7e4393784bfff531
600000004bfff0b1
600000004bffecf5
419cfd707f98d800
4bfffd6c7f1bc378
4bffff703a200000
7fc5f3783c62ffff
38637f707fe4fb78
600000004bfff081
38637fb87fe4fb78
600000004bffecc5
612900143d20c010
7c0004ac79290020
3d00c0107f204f2a
@ -1022,7 +1149,7 @@ f94100a0e8810080
7fe3fb7842000034
4bfff48d3af7ffff
3b9cffff7e439378
600000004bfff009
600000004bffec4d
3ad6ffff2f9f0001
3be00001419e0028
7c0004ac4bfffc78
@ -1030,83 +1157,84 @@ f94100a0e8810080
7c0004ac7d40472a
4bffffb47ce04f2a
3860000138210140
0000000048000ccc
0000000048000cd4
0000128001000000
384290b03c4c0001
384291b83c4c0001
3c62ffff7c0802a6
48000c8938637f28
48000c9138637f70
3f60c010f821ff71
637b10003be00000
4bffef8d7b7b0020
4bffebd17b7b0020
7c0004ac60000000
3f40c0107fe0df2a
7b5a0020635a1004
7fe0d72a7c0004ac
63bd080c3fa0c010
7c0004ac7bbd0020
3fc0c0107fe0ef2a
7bde002063de0810
7fe0f72a7c0004ac
3920000c3f80c010
7b9c0020639c0800
7d20e72a7c0004ac
6063c35038600000
7c0004ac4bfff20d
7c0004ac7fe0ef2a
3920000e7fe0f72a
7d20e72a7c0004ac
4bfff1e938602710
7c0004ac39200200
392000027d20ef2a
7d20f72a7c0004ac
4bfff18d3860000f
4bfff78d3fa0c010
7bbd002063bd080c
7fe0ef2a7c0004ac
7c0004ac39200003
3860000f7d20f72a
392000064bfff171
63de08103fc0c010
7c0004ac7bde0020
3f80c0107fe0f72a
639c08003920000c
7c0004ac7b9c0020
386000007d20e72a
4bfff2096063c350
7fe0ef2a7c0004ac
7fe0f72a7c0004ac
7c0004ac3920000e
386027107d20e72a
392002004bfff1e5
7d20ef2a7c0004ac
7c0004ac3b800001
3860000f7f80f72a
392009204bfff151
7c0004ac39200002
3860000f7d20f72a
7c0004ac4bfff189
392000037fe0ef2a
7d20f72a7c0004ac
4bfff16d3860000f
7c0004ac39200006
3b8000017d20ef2a
7f80f72a7c0004ac
4bfff14d3860000f
7c0004ac39200920
7c0004ac7d20ef2a
3860000f7fe0f72a
386000c84bfff131
392004004bfff165
7d20ef2a7c0004ac
7fe0f72a7c0004ac
4bfff1353860000f
4bfff169386000c8
7c0004ac39200400
7c0004ac7d20ef2a
386000037fe0f72a
386000c84bfff111
4bfffa194bfff145
4bfff7254bfff6d1
4082001c2c230000
7f80df2a7c0004ac
7f80d72a7c0004ac
48000b6038210090
7f80df2a7c0004ac
4bffffec38600001
0100000000000000
3c4c000100000680
3d20c00038428f04
6129200060000000
f922800879290020
612900203d20c000
7c0004ac79290020
3d40001c7d204eea
4bfff10d38600003
4bfff141386000c8
4bfff6cd4bfffa15
2c2300004bfff721
7c0004ac4082001c
7c0004ac7f80df2a
382100907f80d72a
7c0004ac48000b64
386000017f80df2a
000000004bffffec
0000068001000000
384290083c4c0001
600000003d20c000
7929002061292000
3d20c000f9228048
7929002061290020
7d204eea7c0004ac
792906003d40001c
7d295392614a2000
394a0018e9428008
394a0018e9428048
7c0004ac3929ffff
4e8000207d2057ea
0000000000000000
3c4c000100000000
6000000038428ea4
39290010e9228008
6000000038428fa4
39290010e9228048
7d204eea7c0004ac
4082ffe871290008
e94280085469063e
e94280485469063e
7d2057ea7c0004ac
000000004e800020
0000000000000000
38428e603c4c0001
38428f603c4c0001
fbc1fff07c0802a6
3bc3fffffbe1fff8
f821ffd1f8010010
@ -1180,7 +1308,7 @@ f924000039290002
7c6307b43863ffe0
000000004e800020
0000000000000000
38428c103c4c0001
38428d103c4c0001
3d2037367c0802a6
612935347d908026
65293332792907c6
@ -1214,7 +1342,7 @@ fbfd00007fe9fa14
4bfffff07d29f392
0300000000000000
3c4c000100000580
7c0802a638428b04
7c0802a638428c04
f821ffb1480006e9
7c7f1b78eb630000
7cbd2b787c9c2378
@ -1230,7 +1358,7 @@ f821ffb1480006e9
4bffffb8f93f0000
0100000000000000
3c4c000100000580
7c0802a638428a84
7c0802a638428b84
f821ffa148000661
7c9b23787c7d1b78
388000007ca32b78
@ -1261,7 +1389,7 @@ e95d00009b270000
f95d0000394a0001
000000004bffffa8
0000078001000000
384289883c4c0001
38428a883c4c0001
480005397c0802a6
7c741b79f821fed1
38600000f8610060
@ -1270,7 +1398,7 @@ f95d0000394a0001
3ac4ffff3e42ffff
f92100703b410020
3ae0000060000000
3a527fb839228000
3a527ff839228040
f92100783ba10060
ebc1006089250000
419e00102fa90000
@ -1467,23 +1595,39 @@ e8010010ebc1fff0
0000002054524155
000000204d415244
000000204d415242
4853414c46495053
0000000000000020
2020202020202020
203a4d4152422020
0a424b20646c6c25
0000000000000000
000a424b20646c25
2020202020202020
203a4d4152442020
0a424d20646c6c25
0000000000000000
000a424d20646c25
4152442020202020
203a54494e49204d
0a424b20646c6c25
0000000000000000
000a424b20646c25
2020202020202020
203a4b4c43202020
7a484d20646c6c25
000000000000000a
3163616539333236
0a7a484d20646c25
0000000000000000
4c46204950532020
203a444920485341
7832302578323025
0000000078323025
7373657270794320
6f69736e6170532f
253d31464328206e
0000000029783230
696c62616e652020
004441555120676e
006e6f7263694d20
4920646175715b20
005d65646f6d204f
414c462049505320
203a46464f204853
7479622078257830
00000000000a7365
3236343266663032
0000000000000000
0039326232623162
4d4152446574694c
@ -1495,6 +1639,31 @@ e8010010ebc1fff0
20676e69746f6f42
415242206d6f7266
0000000a2e2e2e4d
6620676e69797254
0a2e2e2e6873616c
0000000000000000
2074276e73656f44
6b696c206b6f6f6c
666c65206e612065
00000000000a3436
7070206120746f4e
696220656c343663
0000000a7972616e
6765732079706f43
20642520746e656d
7962207825783028
206f742029736574
00000000000a7025
20676e69746f6f42
415244206d6f7266
0a7825207461204d
0000000000000000
323025203a524448
2520783230252078
7832302520783230
3025207832302520
2078323025207832
0000000a78323025
20676e6979706f43
2064616f6c796170
2e4d415244206f74
@ -1551,7 +1720,6 @@ e8010010ebc1fff0
256d203a74736562
6432302562202c64
0000000000000020
0000000078323025
6f6e204d41524453
207265646e752077
6572617774666f73

File diff suppressed because one or more lines are too long

@ -4,12 +4,12 @@ a602487d05009f42
a64b5a7d14004a39
2402004ca64b7b7d
602100003c200000
6421f000782107c6
6421ff00782107c6
3d80000060213f00
798c07c6618c0000
618c10a4658cf000
618c10e0658cff00
4e8004217d8903a6
0000000048000002
4e8004207c6903a6
0000000000000000
0000000000000000
0000000000000000
@ -510,93 +510,220 @@ a64b5a7d14004a39
0000000000000000
0000000000000000
0000000000000000
3842a1003c4c0001
fbc1fff07c0802a6
f8010010fbe1fff8
3be10020f821fe91
f8a101a0f8810198
f8c101a838800140
38c101987c651b78
7fe3fb78f8e101b0
f92101c0f90101b8
48001735f94101c8
7c7e1b7860000000
4800124d7fe3fb78
3821017060000000
48001cf47fc3f378
0100000000000000
4e80002000000280
0000000000000000
7c0007ac00000000
4e8000204c00012c
392000003d40c000
794a0020614a6004
7d2057aa7c0004ac
6000000060000000
6000000060000000
4e80002060000000
0000000000000000
3c4c000100000000
7c0802a63842a05c
7d800026fbe1fff8
91810008f8010010
48001141f821ff91
7c0802a63842a5c4
fbe1fff8fbc1fff0
f821ff51f8010010
f88100d83be10020
38800080f8a100e0
7c651b78f8c100e8
f8e100f038c100d8
f90100f87fe3fb78
f9410108f9210100
6000000048001af9
7fe3fb787c7e1b78
6000000048001611
7fc3f378382100b0
00000000480020b8
0000028001000000
000000004e800020
0000000000000000
4c00012c7c0007ac
000000004e800020
0000000000000000
3842a5203c4c0001
7d8000267c0802a6
9181000848001ff5
48001505f821fed1
3c62ffff60000000
4bffff3538637c78
4bffff3938637b78
548400023880ffff
7c8026ea7c0004ac
3fe0c0003c62ffff
63ff000838637c98
3c62ffff4bffff11
38637cb87bff0020
7c0004ac4bffff01
63ff000838637b98
3c62ffff4bffff15
38637bb87bff0020
7c0004ac4bffff05
73e900017fe0feea
3c62ffff41820010
4bfffee538637cd0
4d80000073e90002
4bfffee938637bd0
4e00000073e90002
3c62ffff41820010
4bfffecd38637cd8
4e00000073e90004
4bfffed138637bd8
4d80000073e90004
3c62ffff41820010
4bfffeb538637ce0
3bff7f203fe2ffff
4bfffea57fe3fb78
3c80c00041920028
4bfffeb938637be0
4d00000073e90008
3c62ffff41820010
4bfffea138637be8
3b7b7f683f62ffff
4bfffe917f63db78
3c80c000418e0028
7884002060840010
7c8026ea7c0004ac
7884b2823c62ffff
4bfffe7d38637ce8
3c80c000418e004c
7884b5823c62ffff
4bfffe6938637bf8
3c80c0004192004c
7884002060840018
7c8026ea7c0004ac
788465023c62ffff
4bfffe5538637d08
788460223c62ffff
4bfffe4138637c10
608400303c80c000
7c0004ac78840020
3c62ffff7c8026ea
38637d287884b282
3d20c0004bfffe31
38637c287884b282
3d20c0004bfffe1d
7929002061290020
7d204eea7c0004ac
3c62ffff3c80000f
38637d4860844240
4bfffe057c892392
4bfffdfd7fe3fb78
3ca2ffff418e0028
3c62ffff3c82ffff
38847d7838a57d68
4bfffddd38637d80
6000000048000e29
3c62ffff41920020
4bfffdc538637db0
8181000838210070
48001b107d818120
38637dc83c62ffff
3c80f0004bfffda9
792906003c80000f
3c62ffff60844240
38637c407c892392
418a02584bfffded
63bd00383fa0c000
7c0004ac7bbd0020
3d40c0007fa0eeea
614a600439200002
7c0004ac794a0020
3fe0c0007d2057aa
63ff60003920ff9f
7c0004ac7bff0020
7c0004ac7d20ffaa
579c063e7f80feaa
7fc0feaa7c0004ac
7c0004ac57de063e
4bfffd3d7fe0feaa
3c62ffff57ff063e
7fc5f3787fe6fb78
38637c607f84e378
7f89f3784bfffd65
2f8900007d29fb78
7f89f038419e0164
2f8900ff7d29f838
2b9c0001419e0154
2b9e0002409e0374
2b9e0020419e000c
3bffffe8409e0134
2b9f000157ff063e
3fe0c000419d0124
63ff600039200035
7c0004ac7bff0020
3fc0c0007d20ffaa
63de60043b400002
7c0004ac7bde0020
7c0004ac7f40f7aa
7c0004ac7d20ffaa
4bfffc957f80feaa
3c62ffff579c063e
38637c807f84e378
738900024bfffcc5
3c62ffff40820090
4bfffcb138637ca0
7f40f7aa7c0004ac
7c0004ac39200006
4bfffc557d20ffaa
7f40f7aa7c0004ac
7c0004ac39200001
392000007d20ffaa
7d20ffaa7c0004ac
7c0004ac639c0002
7c0004ac7f80ffaa
4bfffc1d7d20f7aa
3b4000053b200002
7f20f7aa7c0004ac
7f40ffaa7c0004ac
7f80feaa7c0004ac
4bfffbf5579c063e
4082ffdc73890001
38637cb83c62ffff
3d40c0004bfffc25
794a0020614a6008
7d20562a7c0004ac
652920005529021e
7c0004ac61291f6b
7f63db787d20572a
7bbd00204bfffbf5
7fa4eb783c62ffff
4bfffbe138637cc8
7f63db783be00001
419200284bfffbd5
3c82ffff3ca2ffff
38a57ce83c62ffff
38637d0038847cf8
48000fbd4bfffbb5
418e002460000000
38637d303c62ffff
386000004bfffb9d
3be0000048000144
4bffffb03ba00000
419e00842fbf0000
38637d483c62ffff
3c9df0004bfffb75
7884002038a00040
4800137d38610070
e921007060000000
614a464c3d400002
79290600794a83e4
7fa95000614a457f
3c62ffff419e0080
4bfffb3138637d60
8941007688610077
8901007489210075
88c1007288e10073
8881007088a10071
3c62fffff8610060
4bfffb0138637de0
38637e103c62ffff
3c80ff004bfffaf5
6084400038a0ffff
7884002054a50422
480011e53c604000
480012f53c604000
3c62ffff60000000
4bfffd7d38637de8
e801001038210070
ebe1fff881810008
7d8181207c0803a6
000000004bfffde4
0000018003000000
4bfffac938637e30
4bffff284bfffb49
2f89000189210075
a1210082409e0010
419e00102f890015
38637d803c62ffff
ebe100904bffff6c
3bc000003f02ffff
3b187d983b2100b0
7bff00207fffea14
7f89f040a12100a8
80810088419d0034
38637dc03c62ffff
4bfffae54bfffa65
2fa3ffffe8610088
38210130419eff58
7d83812081810008
3c9ff00048001b34
7884002038a00038
4800124d7f23cb78
812100b060000000
409e004c2f890001
eb6100c0eb4100d0
7fc4f378eb8100b8
7f66db787f03c378
3f9cf0007b450020
7c9de2144bfff9fd
788400207b450020
480012057f63db78
a12100a660000000
7bff00207fe9fa14
7bde00203bde0001
2b9c00204bffff50
2b9e00ba409efdcc
2b9f0018409efdc4
3c62ffff409efdbc
4bfff9a938637cb0
000000004bfffd78
0000088003000000
612908043d20c010
7c0004ac79290020
3d40c0107c604f2a
@ -653,11 +780,11 @@ ebe1fff881810008
9864000099240001
000000004e800020
0000000000000000
38429c883c4c0001
480018557c0802a6
38429d903c4c0001
4800185d7c0802a6
7c7e1b78f821ff21
38637eb83c62ffff
600000004bfffb71
38637f003c62ffff
600000004bfff7b5
390100603ca08020
3940000460a50003
7d1d43783920002a
@ -708,7 +835,7 @@ ebe1fff881810008
793500203ee2ffff
7d2907b47ed607b4
3b0100703be00000
7f3db2143af77ee0
7f3db2143af77f28
7f5d4a147ebdaa14
3860000f4bfffd75
4bfffca93b800000
@ -749,8 +876,8 @@ ebe1fff881810008
4bffffcc3b400000
7fbfe2142f9f0020
409e006c7fbd0e70
38637ec83c62ffff
600000004bfff889
38637f103c62ffff
600000004bfff4cd
3be000007fc3f378
7f9fe8004bfffb8d
3d40c010419c0070
@ -761,45 +888,45 @@ ebe1fff881810008
7d20572a7c0004ac
4bfffaed3860000b
4bfffb213860000f
4800154c382100e0
48001554382100e0
3c62ffff7cbfe050
7ca501947ca50e70
38637ed07fa4eb78
4bfff80d7ca507b4
38637f187fa4eb78
4bfff4517ca507b4
4bffff8460000000
3bff00017fc3f378
7fff07b44bfffb59
000000004bffff7c
00000b8001000000
384298d83c4c0001
384299e03c4c0001
3d40c0107c0802a6
3920000e614a0800
f8010010794a0020
7c0004acf821ffa1
3c62ffff7d20572a
4bfff7ad38637f90
4bfff3f138637fd0
3821006060000000
7c0803a6e8010010
000000004e800020
0000008001000000
384298803c4c0001
384299883c4c0001
3d40c0107c0802a6
39200001614a0800
f8010010794a0020
7c0004acf821ffa1
3c62ffff7d20572a
4bfff75538637f00
4bfff39938637f48
3821006060000000
7c0803a6e8010010
000000004e800020
0000008001000000
384298283c4c0001
384299303c4c0001
390000807c0802a6
3d40aaaa7d0903a6
614aaaaa3d204000
f821ff8148001401
f821ff8148001409
3929000491490000
4bfff7714200fff8
4bfff3b54200fff8
3940008060000000
7d4903a63d00aaaa
3be000003d204000
@ -811,7 +938,7 @@ f821ff8148001401
3d2040007d0903a6
91490000614a5555
4200fff839290004
600000004bfff715
600000004bfff359
3d00555539400080
3d2040007d4903a6
8149000061085555
@ -820,8 +947,8 @@ f821ff8148001401
4200ffe839290004
419e001c2fbf0000
38a001003c62ffff
38637e007fe4fb78
600000004bfff651
38637e487fe4fb78
600000004bfff295
3ce080203d000008
60e700037d0903a6
392000013d404000
@ -829,7 +956,7 @@ f821ff8148001401
7d2900d0792907e0
7d293838394a0004
912afffc7d294278
4bfff6814200ffe4
4bfff2c54200ffe4
3d00000860000000
7d0903a63ce08020
3d40400060e70003
@ -843,13 +970,13 @@ f821ff8148001401
2fbd00004200ffd4
3c62ffff419e001c
7fa4eb783ca00008
4bfff59d38637e28
4bfff1e138637e70
3920200060000000
7d2903a639400000
794800203d2a1000
394a000139290002
9109000079291764
4bfff5e14200ffe8
4bfff2254200ffe8
3920200060000000
7d2903a639400000
3d2a10003bc00000
@ -860,12 +987,12 @@ f821ff8148001401
2fbe00004200ffdc
3c62ffff419e001c
7fc4f37838a02000
4bfff51538637e50
4bfff15938637e98
7fffea1460000000
7ffff21438600000
409e00a42f9f0000
38637e783c62ffff
600000004bfff4f1
38637ec03c62ffff
600000004bfff135
3d4000047c9602a6
7d4903a678840020
3d49080039200000
@ -873,7 +1000,7 @@ f92a0000794a1f24
4200fff039290001
7c9f20507ff602a6
7fff23963fe06400
600000004bfff525
600000004bfff169
7d3602a67bff0020
792900203d000004
3d4040007d0903a6
@ -881,14 +1008,14 @@ f92a0000794a1f24
7cb602a64200fff8
3ca064007d254850
3c62ffff7ca54b96
38637e887fe4fb78
4bfff46578a50060
38637ed07fe4fb78
4bfff0a978a50060
3860000160000000
4800119438210080
4800119c38210080
0100000000000000
3c4c000100000380
7c0802a63842953c
f821fec1480010ed
7c0802a638429644
f821fec1480010f5
3bc000013fe0c010
7bff002063ff0014
386000004bfffc49
@ -903,15 +1030,15 @@ f821fec1480010ed
7fc0e72a7c0004ac
7fa0ff2a7c0004ac
3b8100703c62ffff
3e02ffff38637f40
600000004bfff3b9
3e02ffff38637f88
600000004bffeffd
fb8100803d22ffff
39297f503de2ffff
39297f983de2ffff
3e42ffff3dc2ffff
f92100983ae10063
3be000003ac10061
39ef7f603a107ee0
3a527f2039ce7f68
39ef7fa83a107f28
3a527f6839ce7fb0
3b20000139210064
3ea0c0103e80c010
39210068f9210088
@ -975,7 +1102,7 @@ e88100904bfff62d
e86100987f604f2a
7fe4fb787fa5eb78
3b6000003b400020
600000004bfff181
600000004bffedc5
4bfff4897fe3fb78
3860000f4bfff51d
4bfff4513a200001
@ -989,25 +1116,25 @@ f94100a0e8810080
394a0004409e0090
409effc02baa0010
7de37b787e248b78
600000004bfff111
600000004bffed55
7fe3fb783b5affff
7b5a00214bfff461
7f7b07b47f7b8a14
7dc373784082ff80
600000004bfff0e9
600000004bffed2d
7c0004ac39200000
7c0004ac7d20a72a
3860000b7d20af2a
3860000f4bfff379
7fe3fb784bfff3ad
7e4393784bfff531
600000004bfff0b1
600000004bffecf5
419cfd707f98d800
4bfffd6c7f1bc378
4bffff703a200000
7fc5f3783c62ffff
38637f707fe4fb78
600000004bfff081
38637fb87fe4fb78
600000004bffecc5
612900143d20c010
7c0004ac79290020
3d00c0107f204f2a
@ -1022,7 +1149,7 @@ f94100a0e8810080
7fe3fb7842000034
4bfff48d3af7ffff
3b9cffff7e439378
600000004bfff009
600000004bffec4d
3ad6ffff2f9f0001
3be00001419e0028
7c0004ac4bfffc78
@ -1030,83 +1157,84 @@ f94100a0e8810080
7c0004ac7d40472a
4bffffb47ce04f2a
3860000138210140
0000000048000ccc
0000000048000cd4
0000128001000000
384290b03c4c0001
384291b83c4c0001
3c62ffff7c0802a6
48000c8938637f28
48000c9138637f70
3f60c010f821ff71
637b10003be00000
4bffef8d7b7b0020
4bffebd17b7b0020
7c0004ac60000000
3f40c0107fe0df2a
7b5a0020635a1004
7fe0d72a7c0004ac
63bd080c3fa0c010
7c0004ac7bbd0020
3fc0c0107fe0ef2a
7bde002063de0810
7fe0f72a7c0004ac
3920000c3f80c010
7b9c0020639c0800
7d20e72a7c0004ac
6063c35038600000
7c0004ac4bfff20d
7c0004ac7fe0ef2a
3920000e7fe0f72a
7d20e72a7c0004ac
4bfff1e938602710
7c0004ac39200200
392000027d20ef2a
7d20f72a7c0004ac
4bfff18d3860000f
4bfff78d3fa0c010
7bbd002063bd080c
7fe0ef2a7c0004ac
7c0004ac39200003
3860000f7d20f72a
392000064bfff171
63de08103fc0c010
7c0004ac7bde0020
3f80c0107fe0f72a
639c08003920000c
7c0004ac7b9c0020
386000007d20e72a
4bfff2096063c350
7fe0ef2a7c0004ac
7fe0f72a7c0004ac
7c0004ac3920000e
386027107d20e72a
392002004bfff1e5
7d20ef2a7c0004ac
7c0004ac3b800001
3860000f7f80f72a
392009204bfff151
7c0004ac39200002
3860000f7d20f72a
7c0004ac4bfff189
392000037fe0ef2a
7d20f72a7c0004ac
4bfff16d3860000f
7c0004ac39200006
3b8000017d20ef2a
7f80f72a7c0004ac
4bfff14d3860000f
7c0004ac39200920
7c0004ac7d20ef2a
3860000f7fe0f72a
386000c84bfff131
392004004bfff165
7d20ef2a7c0004ac
7fe0f72a7c0004ac
4bfff1353860000f
4bfff169386000c8
7c0004ac39200400
7c0004ac7d20ef2a
386000037fe0f72a
386000c84bfff111
4bfffa194bfff145
4bfff7254bfff6d1
4082001c2c230000
7f80df2a7c0004ac
7f80d72a7c0004ac
48000b6038210090
7f80df2a7c0004ac
4bffffec38600001
0100000000000000
3c4c000100000680
3d20c00038428f04
6129200060000000
f922800879290020
612900203d20c000
7c0004ac79290020
3d40001c7d204eea
4bfff10d38600003
4bfff141386000c8
4bfff6cd4bfffa15
2c2300004bfff721
7c0004ac4082001c
7c0004ac7f80df2a
382100907f80d72a
7c0004ac48000b64
386000017f80df2a
000000004bffffec
0000068001000000
384290083c4c0001
600000003d20c000
7929002061292000
3d20c000f9228048
7929002061290020
7d204eea7c0004ac
792906003d40001c
7d295392614a2000
394a0018e9428008
394a0018e9428048
7c0004ac3929ffff
4e8000207d2057ea
0000000000000000
3c4c000100000000
6000000038428ea4
39290010e9228008
6000000038428fa4
39290010e9228048
7d204eea7c0004ac
4082ffe871290008
e94280085469063e
e94280485469063e
7d2057ea7c0004ac
000000004e800020
0000000000000000
38428e603c4c0001
38428f603c4c0001
fbc1fff07c0802a6
3bc3fffffbe1fff8
f821ffd1f8010010
@ -1180,7 +1308,7 @@ f924000039290002
7c6307b43863ffe0
000000004e800020
0000000000000000
38428c103c4c0001
38428d103c4c0001
3d2037367c0802a6
612935347d908026
65293332792907c6
@ -1214,7 +1342,7 @@ fbfd00007fe9fa14
4bfffff07d29f392
0300000000000000
3c4c000100000580
7c0802a638428b04
7c0802a638428c04
f821ffb1480006e9
7c7f1b78eb630000
7cbd2b787c9c2378
@ -1230,7 +1358,7 @@ f821ffb1480006e9
4bffffb8f93f0000
0100000000000000
3c4c000100000580
7c0802a638428a84
7c0802a638428b84
f821ffa148000661
7c9b23787c7d1b78
388000007ca32b78
@ -1261,7 +1389,7 @@ e95d00009b270000
f95d0000394a0001
000000004bffffa8
0000078001000000
384289883c4c0001
38428a883c4c0001
480005397c0802a6
7c741b79f821fed1
38600000f8610060
@ -1270,7 +1398,7 @@ f95d0000394a0001
3ac4ffff3e42ffff
f92100703b410020
3ae0000060000000
3a527fb839228000
3a527ff839228040
f92100783ba10060
ebc1006089250000
419e00102fa90000
@ -1467,23 +1595,39 @@ e8010010ebc1fff0
0000002054524155
000000204d415244
000000204d415242
4853414c46495053
0000000000000020
2020202020202020
203a4d4152422020
0a424b20646c6c25
0000000000000000
000a424b20646c25
2020202020202020
203a4d4152442020
0a424d20646c6c25
0000000000000000
000a424d20646c25
4152442020202020
203a54494e49204d
0a424b20646c6c25
0000000000000000
000a424b20646c25
2020202020202020
203a4b4c43202020
7a484d20646c6c25
000000000000000a
3163616539333236
0a7a484d20646c25
0000000000000000
4c46204950532020
203a444920485341
7832302578323025
0000000078323025
7373657270794320
6f69736e6170532f
253d31464328206e
0000000029783230
696c62616e652020
004441555120676e
006e6f7263694d20
4920646175715b20
005d65646f6d204f
414c462049505320
203a46464f204853
7479622078257830
00000000000a7365
3236343266663032
0000000000000000
0039326232623162
4d4152446574694c
@ -1495,6 +1639,31 @@ e8010010ebc1fff0
20676e69746f6f42
415242206d6f7266
0000000a2e2e2e4d
6620676e69797254
0a2e2e2e6873616c
0000000000000000
2074276e73656f44
6b696c206b6f6f6c
666c65206e612065
00000000000a3436
7070206120746f4e
696220656c343663
0000000a7972616e
6765732079706f43
20642520746e656d
7962207825783028
206f742029736574
00000000000a7025
20676e69746f6f42
415244206d6f7266
0a7825207461204d
0000000000000000
323025203a524448
2520783230252078
7832302520783230
3025207832302520
2078323025207832
0000000a78323025
20676e6979706f43
2064616f6c796170
2e4d415244206f74
@ -1551,7 +1720,6 @@ e8010010ebc1fff0
256d203a74736562
6432302562202c64
0000000000000020
0000000078323025
6f6e204d41524453
207265646e752077
6572617774666f73

File diff suppressed because one or more lines are too long

@ -4,12 +4,12 @@ a602487d05009f42
a64b5a7d14004a39
2402004ca64b7b7d
602100003c200000
6421f000782107c6
6421ff00782107c6
3d80000060213f00
798c07c6618c0000
618c10a4658cf000
618c10e0658cff00
4e8004217d8903a6
0000000048000002
4e8004207c6903a6
0000000000000000
0000000000000000
0000000000000000
@ -510,93 +510,220 @@ a64b5a7d14004a39
0000000000000000
0000000000000000
0000000000000000
384296003c4c0001
fbc1fff07c0802a6
f8010010fbe1fff8
3be10020f821fe91
f8a101a0f8810198
f8c101a838800140
38c101987c651b78
7fe3fb78f8e101b0
f92101c0f90101b8
48000cfdf94101c8
7c7e1b7860000000
480008157fe3fb78
3821017060000000
480012bc7fc3f378
0100000000000000
4e80002000000280
0000000000000000
7c0007ac00000000
4e8000204c00012c
392000003d40c000
794a0020614a6004
7d2057aa7c0004ac
6000000060000000
6000000060000000
4e80002060000000
0000000000000000
3c4c000100000000
7c0802a63842955c
7d800026fbe1fff8
91810008f8010010
48000709f821ff91
7c0802a638429ac4
fbe1fff8fbc1fff0
f821ff51f8010010
f88100d83be10020
38800080f8a100e0
7c651b78f8c100e8
f8e100f038c100d8
f90100f87fe3fb78
f9410108f9210100
6000000048001119
7fe3fb787c7e1b78
6000000048000c31
7fc3f378382100b0
00000000480016d8
0000028001000000
000000004e800020
0000000000000000
4c00012c7c0007ac
000000004e800020
0000000000000000
38429a203c4c0001
7d8000267c0802a6
9181000848001615
48000b25f821fed1
3c62ffff60000000
4bffff3538637d40
4bffff3938637c98
548400023880ffff
7c8026ea7c0004ac
3fe0c0003c62ffff
63ff000838637d60
3c62ffff4bffff11
38637d807bff0020
7c0004ac4bffff01
63ff000838637cb8
3c62ffff4bffff15
38637cd87bff0020
7c0004ac4bffff05
73e900017fe0feea
3c62ffff41820010
4bfffee538637d98
4d80000073e90002
4bfffee938637cf0
4e00000073e90002
3c62ffff41820010
4bfffecd38637da0
4e00000073e90004
4bfffed138637cf8
4d80000073e90004
3c62ffff41820010
4bfffeb538637da8
3bff7fa03fe2ffff
4bfffea57fe3fb78
3c80c00041920028
4bfffeb938637d00
4d00000073e90008
3c62ffff41820010
4bfffea138637d08
3b62804060000000
4bfffe917f63db78
3c80c000418e0028
7884002060840010
7c8026ea7c0004ac
7884b2823c62ffff
4bfffe7d38637db0
3c80c000418e004c
7884b5823c62ffff
4bfffe6938637d18
3c80c0004192004c
7884002060840018
7c8026ea7c0004ac
788465023c62ffff
4bfffe5538637dd0
788460223c62ffff
4bfffe4138637d30
608400303c80c000
7c0004ac78840020
3c62ffff7c8026ea
38637df07884b282
3d20c0004bfffe31
38637d487884b282
3d20c0004bfffe1d
7929002061290020
7d204eea7c0004ac
3c62ffff3c80000f
38637e1060844240
4bfffe057c892392
4bfffdfd7fe3fb78
3ca2ffff418e0028
3c62ffff3c82ffff
38847e4038a57e30
4bfffddd38637e48
6000000048000419
3c62ffff41920020
4bfffdc538637e78
8181000838210070
480010d87d818120
38637e903c62ffff
3c80f0004bfffda9
792906003c80000f
3c62ffff60844240
38637d607c892392
418a02584bfffded
63bd00383fa0c000
7c0004ac7bbd0020
3d40c0007fa0eeea
614a600439200002
7c0004ac794a0020
3fe0c0007d2057aa
63ff60003920ff9f
7c0004ac7bff0020
7c0004ac7d20ffaa
579c063e7f80feaa
7fc0feaa7c0004ac
7c0004ac57de063e
4bfffd3d7fe0feaa
3c62ffff57ff063e
7fc5f3787fe6fb78
38637d807f84e378
7f89f3784bfffd65
2f8900007d29fb78
7f89f038419e0164
2f8900ff7d29f838
2b9c0001419e0154
2b9e0002409e0374
2b9e0020419e000c
3bffffe8409e0134
2b9f000157ff063e
3fe0c000419d0124
63ff600039200035
7c0004ac7bff0020
3fc0c0007d20ffaa
63de60043b400002
7c0004ac7bde0020
7c0004ac7f40f7aa
7c0004ac7d20ffaa
4bfffc957f80feaa
3c62ffff579c063e
38637da07f84e378
738900024bfffcc5
3c62ffff40820090
4bfffcb138637dc0
7f40f7aa7c0004ac
7c0004ac39200006
4bfffc557d20ffaa
7f40f7aa7c0004ac
7c0004ac39200001
392000007d20ffaa
7d20ffaa7c0004ac
7c0004ac639c0002
7c0004ac7f80ffaa
4bfffc1d7d20f7aa
3b4000053b200002
7f20f7aa7c0004ac
7f40ffaa7c0004ac
7f80feaa7c0004ac
4bfffbf5579c063e
4082ffdc73890001
38637dd83c62ffff
3d40c0004bfffc25
794a0020614a6008
7d20562a7c0004ac
652920005529021e
7c0004ac61291f6b
7f63db787d20572a
7bbd00204bfffbf5
7fa4eb783c62ffff
4bfffbe138637de8
7f63db783be00001
419200284bfffbd5
3c82ffff3ca2ffff
38a57e083c62ffff
38637e2038847e18
480006054bfffbb5
418e002460000000
38637e503c62ffff
386000004bfffb9d
3be0000048000144
4bffffb03ba00000
419e00842fbf0000
38637e683c62ffff
3c9df0004bfffb75
7884002038a00040
4800099d38610070
e921007060000000
614a464c3d400002
79290600794a83e4
7fa95000614a457f
3c62ffff419e0080
4bfffb3138637e80
8941007688610077
8901007489210075
88c1007288e10073
8881007088a10071
3c62fffff8610060
4bfffb0138637f00
38637f303c62ffff
3c80ff004bfffaf5
6084400038a0ffff
7884002054a50422
480007ad3c604000
480009153c604000
3c62ffff60000000
4bfffd7d38637eb0
e801001038210070
ebe1fff881810008
7d8181207c0803a6
000000004bfffde4
0000018003000000
4bfffac938637f50
4bffff284bfffb49
2f89000189210075
a1210082409e0010
419e00102f890015
38637ea03c62ffff
ebe100904bffff6c
3bc000003f02ffff
3b187eb83b2100b0
7bff00207fffea14
7f89f040a12100a8
80810088419d0034
38637ee03c62ffff
4bfffae54bfffa65
2fa3ffffe8610088
38210130419eff58
7d83812081810008
3c9ff00048001154
7884002038a00038
4800086d7f23cb78
812100b060000000
409e004c2f890001
eb6100c0eb4100d0
7fc4f378eb8100b8
7f66db787f03c378
3f9cf0007b450020
7c9de2144bfff9fd
788400207b450020
480008257f63db78
a12100a660000000
7bff00207fe9fa14
7bde00203bde0001
2b9c00204bffff50
2b9e00ba409efdcc
2b9f0018409efdc4
3c62ffff409efdbc
4bfff9a938637dd0
000000004bfffd78
0000088003000000
612908043d20c010
7c0004ac79290020
3d40c0107c604f2a
@ -605,24 +732,35 @@ ebe1fff881810008
4e8000207d20572a
0000000000000000
3c4c000100000000
7c0802a63842930c
7c0802a638429414
614a08003d40c010
794a00203920000e
f821ffa1f8010010
7d20572a7c0004ac
3862806060000000
600000004bfff925
e801001038210060
4e8000207c0803a6
0100000000000000
3c4c000100000080
7c0802a6384293bc
614a08003d40c010
794a002039200001
f821ffa1f8010010
7d20572a7c0004ac
38637f803c62ffff
600000004bfffce1
3862802060000000
600000004bfff8cd
e801001038210060
4e8000207c0803a6
0100000000000000
3c4c000100000080
7c0802a6384292b4
7c0802a638429364
7d0903a639000080
3d2040003d40aaaa
48000f55614aaaaa
48000f5d614aaaaa
91490000f821ff81
4200fff839290004
600000004bfffcfd
600000004bfff8e9
3d00aaaa39400080
3d2040007d4903a6
6108aaaa3be00000
@ -633,7 +771,7 @@ e801001038210060
7d0903a63d405555
614a55553d204000
3929000491490000
4bfffca14200fff8
4bfff88d4200fff8
3940008060000000
7d4903a63d005555
610855553d204000
@ -643,7 +781,7 @@ e801001038210060
2fbf00004200ffe8
3c62ffff419e001c
7fe4fb7838a00100
4bfffbdd38637ec8
4bfff7c938637f68
3900010060000000
7d0903a63ce08020
3d40400060e70003
@ -652,7 +790,7 @@ e801001038210060
394a00047d2900d0
7d2942787d293838
4200ffe4912afffc
600000004bfffc0d
600000004bfff7f9
3ce0802039000100
60e700037d0903a6
3ba000003d404000
@ -665,14 +803,14 @@ e801001038210060
4200ffd4394a0004
419e001c2fbd0000
38a001003c62ffff
38637ef07fa4eb78
600000004bfffb29
38637f907fa4eb78
600000004bfff715
3940000039200020
3d2a10007d2903a6
3929000279480020
79291764394a0001
4200ffe891090000
600000004bfffb6d
600000004bfff759
3940000039200020
3bc000007d2903a6
792917643d2a1000
@ -682,12 +820,12 @@ e801001038210060
4200ffdc394a0001
419e001c2fbe0000
38a000203c62ffff
38637f187fc4f378
600000004bfffaa1
38637fb87fc4f378
600000004bfff68d
386000007fffea14
2f9f00007ffff214
3c62ffff409e00ac
4bfffa7d38637f40
4bfff66938637fe0
7c9602a660000000
7884002039400080
392000007d4903a6
@ -696,7 +834,7 @@ e801001038210060
7ff602a64200fff0
3fe0000c7c9f2050
7fff239663ff8000
600000004bfffaad
600000004bfff699
7d3602a67bff0020
7929002039000080
3d4040007d0903a6
@ -705,81 +843,82 @@ e801001038210060
3ca0000c7d254850
3c62ffff60a58000
7fe4fb787ca54b96
78a5032038637f50
600000004bfff9e9
78a5032038637ff0
600000004bfff5d5
3821008038600001
0000000048000ce0
0000000048000ce8
0000038001000000
38428fc03c4c0001
3c62ffff7c0802a6
48000c6138637fa8
384290703c4c0001
600000007c0802a6
48000c6938628048
3f60c010f821ff71
637b10003be00000
4bfff99d7b7b0020
4bfff5897b7b0020
7c0004ac60000000
3f40c0107fe0df2a
7b5a0020635a1004
7fe0d72a7c0004ac
63bd080c3fa0c010
7c0004ac7bbd0020
3fc0c0107fe0ef2a
7bde002063de0810
7fe0f72a7c0004ac
3940000c3d20c010
7929002061290800
4bfffc113fa0c010
7bbd002063bd080c
7fe0ef2a7c0004ac
63de08103fc0c010
7c0004ac7bde0020
3d20c0107fe0f72a
612908003940000c
7c0004ac79290020
7c0004ac7d404f2a
7c0004ac7fe0ef2a
3940000e7fe0f72a
7d404f2a7c0004ac
7c0004ac39200200
392000027d20ef2a
7d20f72a7c0004ac
4bfffb553860000f
7fe0ef2a7c0004ac
7fe0f72a7c0004ac
7c0004ac3940000e
392002007d404f2a
7d20ef2a7c0004ac
7c0004ac39200002
7c0004ac39200003
3860000f7d20f72a
7c0004ac4bfffbb1
392000037fe0ef2a
7d20f72a7c0004ac
4bfffb953860000f
7c0004ac39200006
3b8000017d20ef2a
7f80f72a7c0004ac
4bfffb753860000f
7c0004ac39200920
7c0004ac7d20ef2a
3860000f7fe0f72a
392004004bfffb59
392000064bfffb39
7d20ef2a7c0004ac
7c0004ac3b800001
3860000f7f80f72a
392009204bfffb19
7d20ef2a7c0004ac
7fe0f72a7c0004ac
4bfffb3d38600003
4bfffbd14bfffb7d
4082001c2c230000
7f80df2a7c0004ac
7f80d72a7c0004ac
48000b6038210090
7f80df2a7c0004ac
4bffffec38600001
0100000000000000
3c4c000100000680
3d20c00038428e3c
6129200060000000
f922801079290020
612900203d20c000
7c0004ac79290020
3d40001c7d204eea
4bfffafd3860000f
7c0004ac39200400
7c0004ac7d20ef2a
386000037fe0f72a
4bfffb794bfffae1
2c2300004bfffbcd
7c0004ac4082001c
7c0004ac7f80df2a
382100907f80d72a
7c0004ac48000b64
386000017f80df2a
000000004bffffec
0000068001000000
38428ee83c4c0001
600000003d20c000
7929002061292000
3d20c000f92280d8
7929002061290020
7d204eea7c0004ac
792906003d40001c
7d295392614a2000
394a0018e9428010
394a0018e94280d8
7c0004ac3929ffff
4e8000207d2057ea
0000000000000000
3c4c000100000000
6000000038428ddc
39290010e9228010
6000000038428e84
39290010e92280d8
7d204eea7c0004ac
4082ffe871290008
e94280105469063e
e94280d85469063e
7d2057ea7c0004ac
000000004e800020
0000000000000000
38428d983c4c0001
38428e403c4c0001
fbc1fff07c0802a6
3bc3fffffbe1fff8
f821ffd1f8010010
@ -853,7 +992,7 @@ f924000039290002
7c6307b43863ffe0
000000004e800020
0000000000000000
38428b483c4c0001
38428bf03c4c0001
3d2037367c0802a6
612935347d908026
65293332792907c6
@ -887,7 +1026,7 @@ fbfd00007fe9fa14
4bfffff07d29f392
0300000000000000
3c4c000100000580
7c0802a638428a3c
7c0802a638428ae4
f821ffb1480006e9
7c7f1b78eb630000
7cbd2b787c9c2378
@ -903,7 +1042,7 @@ f821ffb1480006e9
4bffffb8f93f0000
0100000000000000
3c4c000100000580
7c0802a6384289bc
7c0802a638428a64
f821ffa148000661
7c9b23787c7d1b78
388000007ca32b78
@ -934,16 +1073,16 @@ e95d00009b270000
f95d0000394a0001
000000004bffffa8
0000078001000000
384288c03c4c0001
384289683c4c0001
480005397c0802a6
7c741b79f821fed1
38600000f8610060
2fa4000041820068
39210040419e0060
3ac4ffff3e42ffff
3ac4ffff60000000
f92100703b410020
3ae0000060000000
3a527fc039228008
3a428088392280d0
f92100783ba10060
ebc1006089250000
419e00102fa90000
@ -1140,23 +1279,39 @@ e8010010ebc1fff0
0000002054524155
000000204d415244
000000204d415242
4853414c46495053
0000000000000020
2020202020202020
203a4d4152422020
0a424b20646c6c25
0000000000000000
000a424b20646c25
2020202020202020
203a4d4152442020
0a424d20646c6c25
0000000000000000
000a424d20646c25
4152442020202020
203a54494e49204d
0a424b20646c6c25
0000000000000000
000a424b20646c25
2020202020202020
203a4b4c43202020
7a484d20646c6c25
000000000000000a
3163616539333236
0a7a484d20646c25
0000000000000000
4c46204950532020
203a444920485341
7832302578323025
0000000078323025
7373657270794320
6f69736e6170532f
253d31464328206e
0000000029783230
696c62616e652020
004441555120676e
006e6f7263694d20
4920646175715b20
005d65646f6d204f
414c462049505320
203a46464f204853
7479622078257830
00000000000a7365
3236343266663032
0000000000000000
0039326232623162
4d4152446574694c
@ -1168,6 +1323,31 @@ e8010010ebc1fff0
20676e69746f6f42
415242206d6f7266
0000000a2e2e2e4d
6620676e69797254
0a2e2e2e6873616c
0000000000000000
2074276e73656f44
6b696c206b6f6f6c
666c65206e612065
00000000000a3436
7070206120746f4e
696220656c343663
0000000a7972616e
6765732079706f43
20642520746e656d
7962207825783028
206f742029736574
00000000000a7025
20676e69746f6f42
415244206d6f7266
0a7825207461204d
0000000000000000
323025203a524448
2520783230252078
7832302520783230
3025207832302520
2078323025207832
0000000a78323025
20676e6979706f43
2064616f6c796170
2e4d415244206f74
@ -1206,6 +1386,11 @@ e8010010ebc1fff0
696c616974696e49
52445320676e697a
00000a2e2e2e4d41
6f6e204d41524453
207265646e752077
6572617774666f73
6c6f72746e6f6320
000000000000000a
0000000000000000
00000000000000ff
000000000000ffff

File diff suppressed because it is too large Load Diff

@ -49,6 +49,8 @@ filesets:
- xics.vhdl
- syscon.vhdl
- sync_fifo.vhdl
- spi_rxtx.vhdl
- spi_flash_ctrl.vhdl
file_type : vhdlSource-2008

fpga:
@ -119,6 +121,7 @@ targets:
- clk_input
- clk_frequency
- disable_flatten_core
- spi_flash_offset=10485760
tools:
vivado: {part : xc7a200tsbg484-1}
toplevel : toplevel
@ -132,6 +135,7 @@ targets:
- use_litedram=true
- disable_flatten_core
- no_bram
- spi_flash_offset=10485760
generate: [dram_nexys_video]
tools:
vivado: {part : xc7a200tsbg484-1}
@ -146,6 +150,7 @@ targets:
- clk_input
- clk_frequency
- disable_flatten_core
- spi_flash_offset=3145728
tools:
vivado: {part : xc7a35ticsg324-1L}
toplevel : toplevel
@ -159,6 +164,7 @@ targets:
- use_litedram=true
- disable_flatten_core
- no_bram
- spi_flash_offset=3145728
generate: [dram_arty]
tools:
vivado: {part : xc7a35ticsg324-1L}
@ -173,6 +179,7 @@ targets:
- clk_input
- clk_frequency
- disable_flatten_core
- spi_flash_offset=4194304
tools:
vivado: {part : xc7a100ticsg324-1L}
toplevel : toplevel
@ -186,6 +193,7 @@ targets:
- use_litedram=true
- disable_flatten_core
- no_bram
- spi_flash_offset=4194304
generate: [dram_arty]
tools:
vivado: {part : xc7a100ticsg324-1L}
@ -266,3 +274,8 @@ parameters:
description : No internal block RAM (only DRAM and init code carrying payload)
paramtype : generic
default : false

spi_flash_offset:
datatype : int
description : Offset (in bytes) in the SPI flash of the code payload to run
paramtype : generic

@ -0,0 +1,28 @@
library ieee;
use ieee.std_logic_1164.all;

entity s25fl128s is
generic (
LongTimming : boolean := true;
TimingModel : string := "";
tdevice_PU : time := 10 ns;
tdevice_PP256 : time := 10 ns;
tdevice_PP512 : time := 10 ns;
tdevice_WRR : time := 10 ns;
UserPreload : boolean := false
);
PORT (
SI : inout std_ulogic := 'Z';
SO : inout std_ulogic := 'Z';
SCK : in std_ulogic := 'Z';
CSNeg : in std_ulogic := 'Z';
RSTNeg : in std_ulogic := 'Z';
WPNeg : inout std_ulogic := 'Z';
HOLDNeg : inout std_ulogic := 'Z'
);
end entity;

architecture behaviour of s25fl128s is
begin
SO <= '1';
end architecture;

@ -21,8 +21,10 @@ use work.wishbone_types.all;
-- 0xc0000000: SYSCON
-- 0xc0002000: UART0
-- 0xc0004000: XICS ICP
-- 0xc0006000: SPI Flash controller
-- 0xc0100000: LiteDRAM control (CSRs)
-- 0xf0000000: DRAM init code (if any)
-- 0xf0000000: Flash "ROM" mapping
-- 0xff000000: DRAM init code (if any) or flash ROM

entity soc is
generic (
@ -34,7 +36,12 @@ entity soc is
DISABLE_FLATTEN_CORE : boolean := false;
HAS_DRAM : boolean := false;
DRAM_SIZE : integer := 0;
DRAM_INIT_SIZE : integer := 0
DRAM_INIT_SIZE : integer := 0;
HAS_SPI_FLASH : boolean := false;
SPI_FLASH_DLINES : positive := 1;
SPI_FLASH_OFFSET : integer := 0;
SPI_FLASH_DEF_CKDV : natural := 2;
SPI_FLASH_DEF_QUAD : boolean := false
);
port(
rst : in std_ulogic;
@ -52,6 +59,13 @@ entity soc is
uart0_txd : out std_ulogic;
uart0_rxd : in std_ulogic;

-- SPI Flash signals
spi_flash_sck : out std_ulogic;
spi_flash_cs_n : out std_ulogic;
spi_flash_sdat_o : out std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0);
spi_flash_sdat_oe : out std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0);
spi_flash_sdat_i : in std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0);

-- DRAM controller signals
alt_reset : in std_ulogic
);
@ -96,6 +110,12 @@ architecture behaviour of soc is
signal wb_uart0_out : wb_io_slave_out;
signal uart_dat8 : std_ulogic_vector(7 downto 0);

-- SPI Flash controller signals:
signal wb_spiflash_in : wb_io_master_out;
signal wb_spiflash_out : wb_io_slave_out;
signal wb_spiflash_is_reg : std_ulogic;
signal wb_spiflash_is_map : std_ulogic;

-- XICS0 signals:
signal wb_xics0_in : wb_io_master_out;
signal wb_xics0_out : wb_io_slave_out;
@ -127,12 +147,23 @@ architecture behaviour of soc is
signal rst_core : std_ulogic := '1';
signal rst_uart : std_ulogic := '1';
signal rst_xics : std_ulogic := '1';
signal rst_spi : std_ulogic := '1';
signal rst_bram : std_ulogic := '1';
signal rst_dtm : std_ulogic := '1';
signal rst_wbar : std_ulogic := '1';
signal rst_wbdb : std_ulogic := '1';
signal alt_reset_d : std_ulogic;

-- IO branch split:
type slave_io_type is (SLAVE_IO_SYSCON,
SLAVE_IO_UART,
SLAVE_IO_DRAM_INIT,
SLAVE_IO_DRAM_CSR,
SLAVE_IO_ICP_0,
SLAVE_IO_SPI_FLASH_REG,
SLAVE_IO_SPI_FLASH_MAP,
SLAVE_IO_NONE);
signal slave_io_dbg : slave_io_type;
begin

resets: process(system_clk)
@ -140,6 +171,7 @@ begin
if rising_edge(system_clk) then
rst_core <= rst or do_core_reset;
rst_uart <= rst;
rst_spi <= rst;
rst_xics <= rst;
rst_bram <= rst;
rst_dtm <= rst;
@ -154,7 +186,7 @@ begin
generic map(
SIM => SIM,
DISABLE_FLATTEN => DISABLE_FLATTEN_CORE,
ALT_RESET_ADDRESS => (27 downto 0 => '0', others => '1')
ALT_RESET_ADDRESS => (23 downto 0 => '0', others => '1')
)
port map(
clk => system_clk,
@ -389,14 +421,7 @@ begin
-- IO wishbone slave intercon.
--
slave_io_intercon: process(wb_sio_out, wb_syscon_out, wb_uart0_out,
wb_dram_ctrl_out, wb_xics0_out)
-- IO branch split:
type slave_io_type is (SLAVE_IO_SYSCON,
SLAVE_IO_UART,
SLAVE_IO_DRAM_INIT,
SLAVE_IO_DRAM_CSR,
SLAVE_IO_ICP_0,
SLAVE_IO_NONE);
wb_dram_ctrl_out, wb_xics0_out, wb_spiflash_out)
variable slave_io : slave_io_type;

variable match : std_ulogic_vector(31 downto 12);
@ -405,8 +430,10 @@ begin
-- Simple address decoder.
slave_io := SLAVE_IO_NONE;
match := "11" & wb_sio_out.adr(29 downto 12);
if std_match(match, x"F----") then
if std_match(match, x"FF---") and HAS_DRAM then
slave_io := SLAVE_IO_DRAM_INIT;
elsif std_match(match, x"F----") then
slave_io := SLAVE_IO_SPI_FLASH_MAP;
elsif std_match(match, x"C0000") then
slave_io := SLAVE_IO_SYSCON;
elsif std_match(match, x"C0002") then
@ -415,9 +442,16 @@ begin
slave_io := SLAVE_IO_DRAM_CSR;
elsif std_match(match, x"C0004") then
slave_io := SLAVE_IO_ICP_0;
elsif std_match(match, x"C0006") then
slave_io := SLAVE_IO_SPI_FLASH_REG;
end if;
slave_io_dbg <= slave_io;
wb_uart0_in <= wb_sio_out;
wb_uart0_in.cyc <= '0';
wb_spiflash_in <= wb_sio_out;
wb_spiflash_in.cyc <= '0';
wb_spiflash_is_reg <= '0';
wb_spiflash_is_map <= '0';

-- Only give xics 8 bits of wb addr
wb_xics0_in <= wb_sio_out;
@ -451,6 +485,17 @@ begin
when SLAVE_IO_ICP_0 =>
wb_xics0_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_xics0_out;
when SLAVE_IO_SPI_FLASH_MAP =>
-- Clear top bits so they don't make their way to the
-- fash chip.
wb_spiflash_in.adr(29 downto 28) <= "00";
wb_spiflash_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_spiflash_out;
wb_spiflash_is_map <= '1';
when SLAVE_IO_SPI_FLASH_REG =>
wb_spiflash_in.cyc <= wb_sio_out.cyc;
wb_sio_in <= wb_spiflash_out;
wb_spiflash_is_reg <= '1';
when others =>
wb_sio_in.dat <= (others => '1');
wb_sio_in.ack <= wb_sio_out.stb and wb_sio_out.cyc;
@ -467,7 +512,9 @@ begin
BRAM_SIZE => MEMORY_SIZE,
DRAM_SIZE => DRAM_SIZE,
DRAM_INIT_SIZE => DRAM_INIT_SIZE,
CLK_FREQ => CLK_FREQ
CLK_FREQ => CLK_FREQ,
HAS_SPI_FLASH => HAS_SPI_FLASH,
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET
)
port map(
clk => system_clk,
@ -503,6 +550,34 @@ begin
wb_uart0_out.dat <= x"000000" & uart_dat8;
wb_uart0_out.stall <= '0' when wb_uart0_in.cyc = '0' else not wb_uart0_out.ack;

spiflash_gen: if HAS_SPI_FLASH generate
spiflash: entity work.spi_flash_ctrl
generic map (
DATA_LINES => SPI_FLASH_DLINES,
DEF_CLK_DIV => SPI_FLASH_DEF_CKDV,
DEF_QUAD_READ => SPI_FLASH_DEF_QUAD
)
port map(
rst => rst_spi,
clk => system_clk,
wb_in => wb_spiflash_in,
wb_out => wb_spiflash_out,
wb_sel_reg => wb_spiflash_is_reg,
wb_sel_map => wb_spiflash_is_map,
sck => spi_flash_sck,
cs_n => spi_flash_cs_n,
sdat_o => spi_flash_sdat_o,
sdat_oe => spi_flash_sdat_oe,
sdat_i => spi_flash_sdat_i
);
end generate;

no_spi0_gen: if not HAS_SPI_FLASH generate
wb_spiflash_out.dat <= (others => '1');
wb_spiflash_out.ack <= wb_spiflash_in.cyc and wb_spiflash_in.stb;
wb_spiflash_out.stall <= wb_spiflash_in.cyc and not wb_spiflash_out.ack;
end generate;

xics0: entity work.xics
generic map(
LEVEL_NUM => 16

@ -0,0 +1,601 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.wishbone_types.all;

entity spi_flash_ctrl is
generic (
-- Default config for auto-mode
DEF_CLK_DIV : natural := 2; -- Clock divider SCK = CLK/((CLK_DIV+1)*2)
DEF_QUAD_READ : boolean := false; -- Use quad read with 8 clk dummy

-- Number of data lines (1=MISO/MOSI, otherwise 2 or 4)
DATA_LINES : positive := 1
);
port (
clk : in std_ulogic;
rst : in std_ulogic;

-- Wishbone ports:
wb_in : in wb_io_master_out;
wb_out : out wb_io_slave_out;

-- Wishbone extra selects
wb_sel_reg : in std_ulogic;
wb_sel_map : in std_ulogic;

-- SPI port
sck : out std_ulogic;
cs_n : out std_ulogic;
sdat_o : out std_ulogic_vector(DATA_LINES-1 downto 0);
sdat_oe : out std_ulogic_vector(DATA_LINES-1 downto 0);
sdat_i : in std_ulogic_vector(DATA_LINES-1 downto 0)
);
end entity spi_flash_ctrl;

architecture rtl of spi_flash_ctrl is

-- Register indices
constant SPI_REG_BITS : positive := 3;

-- Register addresses (matches wishbone addr downto 2, ie, 4 bytes per reg)
constant SPI_REG_DATA : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "000";
constant SPI_REG_CTRL : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "001";
constant SPI_REG_AUTO_CFG : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "010";
constant SPI_REG_INVALID : std_ulogic_vector(SPI_REG_BITS-1 downto 0) := "111";

-- Control register
signal ctrl_reg : std_ulogic_vector(15 downto 0) := (others => '0');
alias ctrl_reset : std_ulogic is ctrl_reg(0);
alias ctrl_cs : std_ulogic is ctrl_reg(1);
alias ctrl_rsrv1 : std_ulogic is ctrl_reg(2);
alias ctrl_rsrv2 : std_ulogic is ctrl_reg(3);
alias ctrl_div : std_ulogic_vector(7 downto 0) is ctrl_reg(15 downto 8);

-- Auto mode config register
signal auto_cfg_reg : std_ulogic_vector(29 downto 0) := (others => '0');
alias auto_cfg_cmd : std_ulogic_vector(7 downto 0) is auto_cfg_reg(7 downto 0);
alias auto_cfg_dummies : std_ulogic_vector(2 downto 0) is auto_cfg_reg(10 downto 8);
alias auto_cfg_mode : std_ulogic_vector(1 downto 0) is auto_cfg_reg(12 downto 11);
alias auto_cfg_addr4 : std_ulogic is auto_cfg_reg(13);
alias auto_cfg_rsrv1 : std_ulogic is auto_cfg_reg(14);
alias auto_cfg_rsrv2 : std_ulogic is auto_cfg_reg(15);
alias auto_cfg_div : std_ulogic_vector(7 downto 0) is auto_cfg_reg(23 downto 16);
alias auto_cfg_cstout : std_ulogic_vector(5 downto 0) is auto_cfg_reg(29 downto 24);

-- Constants below match top 2 bits of rxtx "mode"
constant SPI_AUTO_CFG_MODE_SINGLE : std_ulogic_vector(1 downto 0) := "00";
constant SPI_AUTO_CFG_MODE_DUAL : std_ulogic_vector(1 downto 0) := "10";
constant SPI_AUTO_CFG_MODE_QUAD : std_ulogic_vector(1 downto 0) := "11";

-- Signals to rxtx
signal cmd_valid : std_ulogic;
signal cmd_clk_div : natural range 0 to 255;
signal cmd_mode : std_ulogic_vector(2 downto 0);
signal cmd_ready : std_ulogic;
signal d_clks : std_ulogic_vector(2 downto 0);
signal d_rx : std_ulogic_vector(7 downto 0);
signal d_tx : std_ulogic_vector(7 downto 0);
signal d_ack : std_ulogic;
signal bus_idle : std_ulogic;

-- Latch to track that we have a pending read
signal pending_read : std_ulogic;

-- Wishbone latches
signal wb_req : wb_io_master_out;
signal wb_stash : wb_io_master_out;
signal wb_rsp : wb_io_slave_out;

-- Wishbone decode
signal wb_valid : std_ulogic;
signal wb_reg_valid : std_ulogic;
signal wb_reg_dat_v : std_ulogic;
signal wb_map_valid : std_ulogic;
signal wb_reg : std_ulogic_vector(SPI_REG_BITS-1 downto 0);

-- Auto mode clock counts XXX FIXME: Look at reasonable values based
-- on system clock maybe ? Or make them programmable.
constant CS_DELAY_ASSERT : integer := 1; -- CS low to cmd
constant CS_DELAY_RECOVERY : integer := 10; -- CS high to CS low
constant DEFAULT_CS_TIMEOUT : integer := 32;

-- Automatic mode state
type auto_state_t is (AUTO_IDLE, AUTO_CS_ON, AUTO_CMD,
AUTO_ADR0, AUTO_ADR1, AUTO_ADR2, AUTO_ADR3,
AUTO_DUMMY,
AUTO_DAT0, AUTO_DAT1, AUTO_DAT2, AUTO_DAT3,
AUTO_DAT0_DATA, AUTO_DAT1_DATA, AUTO_DAT2_DATA, AUTO_DAT3_DATA,
AUTO_SEND_ACK, AUTO_WAIT_REQ, AUTO_RECOVERY);
-- Automatic mode signals
signal auto_cs : std_ulogic;
signal auto_cmd_valid : std_ulogic;
signal auto_cmd_mode : std_ulogic_vector(2 downto 0);
signal auto_d_txd : std_ulogic_vector(7 downto 0);
signal auto_d_clks : std_ulogic_vector(2 downto 0);
signal auto_data_next : std_ulogic_vector(wb_out.dat'left downto 0);
signal auto_cnt_next : integer range 0 to 63;
signal auto_ack : std_ulogic;
signal auto_next : auto_state_t;
signal auto_lad_next : std_ulogic_vector(31 downto 0);
signal auto_latch_adr : std_ulogic;

-- Automatic mode latches
signal auto_data : std_ulogic_vector(wb_out.dat'left downto 0) := (others => '0');
signal auto_cnt : integer range 0 to 63 := 0;
signal auto_state : auto_state_t := AUTO_IDLE;
signal auto_last_addr : std_ulogic_vector(31 downto 0);

begin

-- Instanciate low level shifter
spi_rxtx: entity work.spi_rxtx
generic map (
DATA_LINES => DATA_LINES
)
port map(
rst => rst,
clk => clk,
clk_div_i => cmd_clk_div,
cmd_valid_i => cmd_valid,
cmd_ready_o => cmd_ready,
cmd_mode_i => cmd_mode,
cmd_clks_i => d_clks,
cmd_txd_i => d_tx,
d_rxd_o => d_rx,
d_ack_o => d_ack,
bus_idle_o => bus_idle,
sck => sck,
sdat_o => sdat_o,
sdat_oe => sdat_oe,
sdat_i => sdat_i
);

-- Valid wb command
wb_valid <= wb_req.stb and wb_req.cyc;
wb_reg_valid <= wb_valid and wb_sel_reg;
wb_map_valid <= wb_valid and wb_sel_map;

-- Register decode. For map accesses, make it look like "invalid"
wb_reg <= wb_req.adr(SPI_REG_BITS+1 downto 2) when wb_reg_valid else SPI_REG_INVALID;

-- Shortcut because we test that a lot: data register access
wb_reg_dat_v <= '1' when wb_reg = SPI_REG_DATA else '0';

-- Wishbone request -> SPI request
wb_request_sync: process(clk)
begin
if rising_edge(clk) then
-- We need to latch whether a read is in progress to block
-- a subsequent store, otherwise the acks will collide.
--
-- We are heavy handed and force a wait for an idle bus if
-- a store is behind a load. Shouldn't happen with flashes
-- in practice.
--
if cmd_valid = '1' and cmd_ready = '1' then
pending_read <= '1';
elsif bus_idle = '1' then
pending_read <= '0';
end if;
end if;
end process;

wb_request_comb: process(all)
begin
if ctrl_cs = '1' then
-- Data register access (see wb_request_sync)
cmd_valid <= wb_reg_dat_v and not (pending_read and wb_req.we);

-- Clock divider from control reg
cmd_clk_div <= to_integer(unsigned(ctrl_div));

-- Mode based on sel
if wb_req.sel = "0010" then
-- dual mode
cmd_mode <= "10" & wb_req.we;
d_clks <= "011";
elsif wb_req.sel = "0100" then
-- quad mode
cmd_mode <= "11" & wb_req.we;
d_clks <= "001";
else
-- single bit
cmd_mode <= "01" & wb_req.we;
d_clks <= "111";
end if;
d_tx <= wb_req.dat(7 downto 0);
cs_n <= not ctrl_cs;
else
cmd_valid <= auto_cmd_valid;
cmd_mode <= auto_cmd_mode;
cmd_clk_div <= to_integer(unsigned(auto_cfg_div));
d_tx <= auto_d_txd;
d_clks <= auto_d_clks;
cs_n <= not auto_cs;
end if;
end process;

-- Generate wishbone responses
--
-- Note: wb_out and wb_in should only appear in this synchronous process
--
-- Everything else should work on wb_req and wb_rsp
wb_response_sync: process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
wb_out.ack <= '0';
wb_out.stall <= '0';
else
-- Latch wb responses as well for 1 cycle. Stall is updated
-- below
wb_out <= wb_rsp;

-- Implement a stash buffer. If we are stalled and stash is
-- free, fill it up. This will generate a WB stall on the
-- next cycle.
if wb_rsp.stall = '1' and wb_out.stall = '0' and
wb_in.cyc = '1' and wb_in.stb = '1' then
wb_stash <= wb_in;
wb_out.stall <= '1';
end if;

-- We aren't stalled, see what we can do
if wb_rsp.stall = '0' then
if wb_out.stall = '1' then
-- Something in stash ! use it and clear stash
wb_req <= wb_stash;
wb_out.stall <= '0';
else
-- Nothing in stash, grab request from WB
if wb_in.cyc = '1' then
wb_req <= wb_in;
else
wb_req.cyc <= wb_in.cyc;
wb_req.stb <= wb_in.stb;
end if;
end if;
end if;
end if;
end if;
end process;

wb_response_comb: process(all)
begin
-- Defaults
wb_rsp.ack <= '0';
wb_rsp.dat <= x"00" & d_rx & d_rx & d_rx;
wb_rsp.stall <= '0';

-- Depending on the access type...
if wb_map_valid = '1' then

-- Memory map access
wb_rsp.stall <= not auto_ack; -- XXX FIXME: Allow pipelining
wb_rsp.ack <= auto_ack;
wb_rsp.dat <= auto_data;

elsif ctrl_cs = '1' and wb_reg = SPI_REG_DATA then

-- Data register in manual mode
--
-- Stall stores if there's a pending read to avoid
-- acks colliding. Otherwise accept all accesses
-- immediately if rxtx is ready.
--
-- Note: This must match the logic setting cmd_valid
-- in wb_request_comb.
--
-- We also ack stores immediately when accepted. Loads
-- are handled separately further down.
--
if wb_req.we = '1' and pending_read = '1' then
wb_rsp.stall <= '1';
else
wb_rsp.ack <= wb_req.we and cmd_ready;
wb_rsp.stall <= not cmd_ready;
end if;

-- Note: loads acks are handled elsewhere
elsif wb_reg_valid = '1' then

-- Normal register access
--
-- Normally single cycle but ensure any auto-mode or manual
-- operation is complete first
--
if auto_state = AUTO_IDLE and bus_idle = '1' then
wb_rsp.ack <= '1';
wb_rsp.stall <= '0';

case wb_reg is
when SPI_REG_CTRL =>
wb_rsp.dat <= (ctrl_reg'range => ctrl_reg, others => '0');
when SPI_REG_AUTO_CFG =>
wb_rsp.dat <= (auto_cfg_reg'range => auto_cfg_reg, others => '0');
when others => null;
end case;
else
wb_rsp.stall <= '1';
end if;
end if;

-- For loads in manual mode, we've accepted the command early
-- so none of the above connditions might be true. We thus need
-- to send the ack whenever we are getting it from rxtx.
--
-- This shouldn't collide with any of the above acks because we hold
-- normal register accesses and stores when there is a pending
-- load or the bus is busy.
--
if ctrl_cs = '1' and d_ack = '1' then
assert pending_read = '1' report "d_ack without pending read !" severity failure;
wb_rsp.ack <= '1';
end if;
end process;

-- Automatic mode state machine
auto_sync: process(clk)
begin
if rising_edge(clk) then
auto_state <= auto_next;
auto_cnt <= auto_cnt_next;
auto_data <= auto_data_next;
if auto_latch_adr = '1' then
auto_last_addr <= auto_lad_next;
end if;
end if;
end process;

auto_comb: process(all)
variable addr : std_ulogic_vector(31 downto 0);
variable req_is_next : boolean;

function mode_to_clks(mode: std_ulogic_vector(1 downto 0)) return std_ulogic_vector is
begin
if mode = SPI_AUTO_CFG_MODE_QUAD then
return "001";
elsif mode = SPI_AUTO_CFG_MODE_DUAL then
return "011";
else
return "111";
end if;
end function;
begin
-- Default outputs
auto_ack <= '0';
auto_cs <= '0';
auto_cmd_valid <= '0';
auto_d_txd <= x"00";
auto_cmd_mode <= "001";
auto_d_clks <= "111";
auto_latch_adr <= '0';

-- Default next state
auto_next <= auto_state;
auto_cnt_next <= auto_cnt;
auto_data_next <= auto_data;

-- Convert wishbone address into a flash address. We mask
-- off the 4 top address bits to get rid of the "f" there.
addr := "00" & wb_req.adr(29 downto 2) & "00";

-- Calculate the next address for store & compare later
auto_lad_next <= std_ulogic_vector(unsigned(addr) + 4);

-- Match incoming request address with next address
req_is_next := addr = auto_last_addr;

-- XXX TODO:
-- - Support < 32-bit accesses

-- Reset
if rst = '1' or ctrl_reset = '1' then
auto_cs <= '0';
auto_cnt_next <= 0;
auto_next <= AUTO_IDLE;
else
-- Run counter
if auto_cnt /= 0 then
auto_cnt_next <= auto_cnt - 1;
end if;

-- Automatic CS is set whenever state isn't IDLE or RECOVERY
if auto_state /= AUTO_IDLE and
auto_state /= AUTO_RECOVERY then
auto_cs <= '1';
end if;

-- State machine
case auto_state is
when AUTO_IDLE =>
-- Access to the memory map only when manual CS isn't set
if wb_map_valid = '1' and ctrl_cs = '0' then
-- Ignore writes, we don't support them yet
if wb_req.we = '1' then
auto_ack <= '1';
else
-- Start machine with CS assertion delay
auto_next <= AUTO_CS_ON;
auto_cnt_next <= CS_DELAY_ASSERT;
end if;
end if;
when AUTO_CS_ON =>
if auto_cnt = 0 then
-- CS asserted long enough, send command
auto_next <= AUTO_CMD;
end if;
when AUTO_CMD =>
auto_d_txd <= auto_cfg_cmd;
auto_cmd_valid <= '1';
if cmd_ready = '1' then
if auto_cfg_addr4 = '1' then
auto_next <= AUTO_ADR3;
else
auto_next <= AUTO_ADR2;
end if;
end if;
when AUTO_ADR3 =>
auto_d_txd <= addr(31 downto 24);
auto_cmd_valid <= '1';
if cmd_ready = '1' then
auto_next <= AUTO_ADR2;
end if;
when AUTO_ADR2 =>
auto_d_txd <= addr(23 downto 16);
auto_cmd_valid <= '1';
if cmd_ready = '1' then
auto_next <= AUTO_ADR1;
end if;
when AUTO_ADR1 =>
auto_d_txd <= addr(15 downto 8);
auto_cmd_valid <= '1';
if cmd_ready = '1' then
auto_next <= AUTO_ADR0;
end if;
when AUTO_ADR0 =>
auto_d_txd <= addr(7 downto 0);
auto_cmd_valid <= '1';
if cmd_ready = '1' then
if auto_cfg_dummies = "000" then
auto_next <= AUTO_DAT0;
else
auto_next <= AUTO_DUMMY;
end if;
end if;
when AUTO_DUMMY =>
auto_cmd_valid <= '1';
auto_d_clks <= auto_cfg_dummies;
if cmd_ready = '1' then
auto_next <= AUTO_DAT0;
end if;
when AUTO_DAT0 =>
auto_cmd_valid <= '1';
auto_cmd_mode <= auto_cfg_mode & "0";
auto_d_clks <= mode_to_clks(auto_cfg_mode);
if cmd_ready = '1' then
auto_next <= AUTO_DAT0_DATA;
end if;
when AUTO_DAT0_DATA =>
if d_ack = '1' then
auto_data_next(7 downto 0) <= d_rx;
auto_next <= AUTO_DAT1;
end if;
when AUTO_DAT1 =>
auto_cmd_valid <= '1';
auto_cmd_mode <= auto_cfg_mode & "0";
auto_d_clks <= mode_to_clks(auto_cfg_mode);
if cmd_ready = '1' then
auto_next <= AUTO_DAT1_DATA;
end if;
when AUTO_DAT1_DATA =>
if d_ack = '1' then
auto_data_next(15 downto 8) <= d_rx;
auto_next <= AUTO_DAT2;
end if;
when AUTO_DAT2 =>
auto_cmd_valid <= '1';
auto_cmd_mode <= auto_cfg_mode & "0";
auto_d_clks <= mode_to_clks(auto_cfg_mode);
if cmd_ready = '1' then
auto_next <= AUTO_DAT2_DATA;
end if;
when AUTO_DAT2_DATA =>
if d_ack = '1' then
auto_data_next(23 downto 16) <= d_rx;
auto_next <= AUTO_DAT3;
end if;
when AUTO_DAT3 =>
auto_cmd_valid <= '1';
auto_cmd_mode <= auto_cfg_mode & "0";
auto_d_clks <= mode_to_clks(auto_cfg_mode);
if cmd_ready = '1' then
auto_next <= AUTO_DAT3_DATA;
end if;
when AUTO_DAT3_DATA =>
if d_ack = '1' then
auto_data_next(31 downto 24) <= d_rx;
auto_next <= AUTO_SEND_ACK;
auto_latch_adr <= '1';
end if;
when AUTO_SEND_ACK =>
auto_ack <= '1';
auto_cnt_next <= to_integer(unsigned(auto_cfg_cstout));
auto_next <= AUTO_WAIT_REQ;
when AUTO_WAIT_REQ =>
-- Incoming bus request we can take ? Otherwise do we need
-- to cancel the wait ?
if wb_map_valid = '1' and req_is_next and wb_req.we = '0' then
auto_next <= AUTO_DAT0;
elsif wb_map_valid = '1' or wb_reg_valid = '1' or auto_cnt = 0 then
-- This means we can drop the CS right on the next clock.
-- We make the assumption here that the two cycles min
-- spent in AUTO_SEND_ACK and AUTO_WAIT_REQ are long enough
-- to deassert CS. If that doesn't hold true in the future,
-- add another state.
auto_cnt_next <= CS_DELAY_RECOVERY;
auto_next <= AUTO_RECOVERY;
end if;
when AUTO_RECOVERY =>
if auto_cnt = 0 then
auto_next <= AUTO_IDLE;
end if;
end case;
end if;
end process;

-- Register write sync machine
reg_write: process(clk)
function reg_wr(r : in std_ulogic_vector;
w : in wb_io_master_out) return std_ulogic_vector is
variable b : natural range 0 to 31;
variable t : std_ulogic_vector(r'range);
begin
t := r;
for i in r'range loop
if w.sel(i/8) = '1' then
t(i) := w.dat(i);
end if;
end loop;
return t;
end function;
begin
if rising_edge(clk) then
-- Reset auto-clear
if rst = '1' or ctrl_reset = '1' then
ctrl_reset <= '0';
ctrl_cs <= '0';
ctrl_rsrv1 <= '0';
ctrl_rsrv2 <= '0';
ctrl_div <= std_ulogic_vector(to_unsigned(DEF_CLK_DIV, 8));
if DEF_QUAD_READ then
auto_cfg_cmd <= x"6b";
auto_cfg_dummies <= "111";
auto_cfg_mode <= SPI_AUTO_CFG_MODE_QUAD;
else
auto_cfg_cmd <= x"03";
auto_cfg_dummies <= "000";
auto_cfg_mode <= SPI_AUTO_CFG_MODE_SINGLE;
end if;
auto_cfg_addr4 <= '0';
auto_cfg_rsrv1 <= '0';
auto_cfg_rsrv2 <= '0';
auto_cfg_div <= std_ulogic_vector(to_unsigned(DEF_CLK_DIV, 8));
auto_cfg_cstout <= std_ulogic_vector(to_unsigned(DEFAULT_CS_TIMEOUT, 6));
end if;

if wb_reg_valid = '1' and wb_req.we = '1' and auto_state = AUTO_IDLE and bus_idle = '1' then
if wb_reg = SPI_REG_CTRL then
ctrl_reg <= reg_wr(ctrl_reg, wb_req);
end if;
if wb_reg = SPI_REG_AUTO_CFG then
auto_cfg_reg <= reg_wr(auto_cfg_reg, wb_req);
end if;
end if;
end if;
end process;

end architecture;

@ -0,0 +1,386 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library work;
use work.wishbone_types.all;

entity spi_rxtx is
generic (
DATA_LINES : positive := 1; -- Number of data lines
-- 1=MISO/MOSI, otherwise 2 or 4
INPUT_DELAY : natural range 0 to 1 := 1 -- Delay latching of SPI input:
-- 0=no delay, 1=clk/2
);
port (
clk : in std_ulogic;
rst : in std_ulogic;

--
-- Clock divider
-- SCK = CLK/((CLK_DIV+1)*2) : 0=CLK/2, 1=CLK/4, 2=CLK/6....
--
-- This need to be changed before a command.
-- XX TODO add handshake
clk_div_i : in natural range 0 to 255;

--
-- Command port (includes write data)
--

-- Valid & ready: command sampled when valid=1 and ready=1
cmd_valid_i : in std_ulogic;
cmd_ready_o : out std_ulogic;

-- Command modes:
-- 000 : Single bit read+write
-- 010 : Single bit read
-- 011 : Single bit write
-- 100 : Dual read
-- 101 : Dual write
-- 110 : Quad read
-- 111 : Quad write
cmd_mode_i : in std_ulogic_vector(2 downto 0);

-- # clocks-1 in a command (#bits-1)
cmd_clks_i : in std_ulogic_vector(2 downto 0);

-- Write data (sampled with command)
cmd_txd_i : in std_ulogic_vector(7 downto 0);

--
-- Read data port. Data valid when d_ack=1, no ready
-- signal, receiver must be ready
--
d_rxd_o : out std_ulogic_vector(7 downto 0);
d_ack_o : out std_ulogic := '0';

-- Set when all commands are done. Needed for callers to know when
-- to release CS#
bus_idle_o : out std_ulogic;

--
-- SPI port. These might need to go into special IOBUFs or STARTUPE2 on
-- Xilinx.
--
-- Data lines are organized as follow:
--
-- DATA_LINES = 1
--
-- sdat_o(0) is MOSI (master output slave input)
-- sdat_i(0) is MISO (master input slave output)
--
-- DATA_LINES > 1
--
-- sdat_o(0..n) are DQ(0..n)
-- sdat_i(0..n) are DQ(0..n)
--
-- as such, beware that:
--
-- sdat_o(0) is MOSI (master output slave input)
-- sdat_i(1) is MISO (master input slave output)
--
-- In order to leave dealing with the details of how to wire the tristate
-- and bidirectional pins to the system specific toplevel, we separate
-- the input and output signals, and provide a "sdat_oe" signal which
-- is the "output enable" of each line.
--
sck : out std_ulogic;
sdat_o : out std_ulogic_vector(DATA_LINES-1 downto 0);
sdat_oe : out std_ulogic_vector(DATA_LINES-1 downto 0);
sdat_i : in std_ulogic_vector(DATA_LINES-1 downto 0)
);
end entity spi_rxtx;

architecture rtl of spi_rxtx is

-- Internal clock signal. Output is gated by sck_en_int
signal sck_0 : std_ulogic;
signal sck_1 : std_ulogic;

-- Clock divider latch
signal clk_div : natural range 0 to 255;

-- 1 clk pulses indicating when to send and when to latch
--
-- Typically for CPOL=CPHA
-- sck_send is sck falling edge
-- sck_recv is sck rising edge
--
-- Those pulses are generated "ahead" of the corresponding
-- edge so then are "seen" at the rising sysclk edge matching
-- the corresponding sck edgeg.
signal sck_send : std_ulogic;
signal sck_recv : std_ulogic;

-- Command mode latch
signal cmd_mode : std_ulogic_vector(2 downto 0);
-- Output shift register (use fifo ?)
signal oreg : std_ulogic_vector(7 downto 0);

-- Input latch
signal dat_i_l : std_ulogic_vector(DATA_LINES-1 downto 0);

-- Data ack latch
signal dat_ack_l : std_ulogic;

-- Delayed recv signal for the read machine
signal sck_recv_d : std_ulogic := '0';

-- Input shift register (use fifo ?)
signal ireg : std_ulogic_vector(7 downto 0) := (others => '0');

-- Bit counter
signal bit_count : std_ulogic_vector(2 downto 0);

-- Next/start/stop command signals. Set when counter goes negative
signal next_cmd : std_ulogic;
signal start_cmd : std_ulogic;
signal end_cmd : std_ulogic;

function data_single(mode : std_ulogic_vector(2 downto 0)) return boolean is
begin
return mode(2) = '0';
end;
function data_dual(mode : std_ulogic_vector(2 downto 0)) return boolean is
begin
return mode(2 downto 1) = "10";
end;
function data_quad(mode : std_ulogic_vector(2 downto 0)) return boolean is
begin
return mode(2 downto 1) = "11";
end;
function data_write(mode : std_ulogic_vector(2 downto 0)) return boolean is
begin
return mode(0) = '1';
end;

type state_t is (STANDBY, DATA);
signal state : state_t := STANDBY;
begin

-- We don't support multiple data lines at this point
assert DATA_LINES = 1 or DATA_LINES = 2 or DATA_LINES = 4
report "Unsupported DATA_LINES configuration !" severity failure;

-- Clock generation
--
-- XX HARD WIRE CPOL=1 CPHA=1 for now
sck_gen: process(clk)
variable counter : integer range 0 to 255;
begin
if rising_edge(clk) then
if rst = '1' then
sck_0 <= '1';
sck_1 <= '1';
sck_send <= '0';
sck_recv <= '0';
clk_div <= 0;
elsif counter = clk_div then
counter := 0;

-- Latch new divider
clk_div <= clk_div_i;

-- Internal version of the clock
sck_0 <= not sck_0;

-- Generate send/receive pulses to run out state machine
sck_recv <= not sck_0;
sck_send <= sck_0;
else
counter := counter + 1;
sck_recv <= '0';
sck_send <= '0';
end if;

-- Delayed version of the clock to line up with
-- the up/down signals
--
-- XXX Figure out a better way
if (state = DATA and end_cmd = '0') or (next_cmd = '1' and cmd_valid_i = '1') then
sck_1 <= sck_0;
else
sck_1 <= '1';
end if;
end if;
end process;

-- SPI clock
sck <= sck_1;

-- Ready to start the next command. This is set on the clock down
-- after the counter goes negative.
-- Note: in addition to latching a new command, this will cause
-- the counter to be reloaded.
next_cmd <= '1' when sck_send = '1' and bit_count = "111" else '0';

-- We start a command when we have a valid request at that time.
start_cmd <= next_cmd and cmd_valid_i;
-- We end commands if we get start_cmd and there's nothing to
-- start. This sends up to standby holding CLK high
end_cmd <= next_cmd and not cmd_valid_i;

-- Generate cmd_ready. It will go up and down with sck, we could
-- gate it with cmd_valid to make it look cleaner but that would
-- add yet another combinational loop on the wishbone that I'm
-- to avoid.
cmd_ready_o <= next_cmd;

-- Generate bus_idle_o
bus_idle_o <= '1' when state = STANDBY else '0';

-- Main state machine. Also generates cmd and data ACKs
machine: process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
state <= STANDBY;
cmd_mode <= "000";
else
-- First clk down of a new cycle. Latch a request if any
-- or get out.
if start_cmd = '1' then
state <= DATA;
cmd_mode <= cmd_mode_i;
elsif end_cmd = '1' then
state <= STANDBY;
end if;
end if;
end if;
end process;

-- Run the bit counter in DATA state. It will update on rising
-- SCK edges. It starts at d_clks on command latch
count_bit: process(clk)
begin
if rising_edge(clk) then
if start_cmd = '1' then
bit_count <= cmd_clks_i;
elsif state /= DATA then
bit_count <= (others => '1');
elsif sck_recv = '1' then
bit_count <= std_ulogic_vector(unsigned(bit_count) - 1);
end if;
end if;
end process;

-- Shift output data
shift_out: process(clk)
begin
if rising_edge(clk) then
-- Starting a command
if start_cmd = '1' then
oreg <= cmd_txd_i(7 downto 0);
elsif sck_send = '1' then
-- Get shift amount
if data_single(cmd_mode) then
oreg <= oreg(6 downto 0) & '0';
elsif data_dual(cmd_mode) then
oreg <= oreg(5 downto 0) & "00";
else
oreg <= oreg(3 downto 0) & "0000";
end if;
end if;
end if;
end process;

-- Data out
sdat_o(0) <= oreg(7);
dl2: if DATA_LINES > 1 generate
sdat_o(1) <= oreg(6);
end generate;
dl4: if DATA_LINES > 2 generate
sdat_o(2) <= oreg(5);
sdat_o(3) <= oreg(4);
end generate;

-- Data lines direction
dlines: process(all)
begin
for i in DATA_LINES-1 downto 0 loop
sdat_oe(i) <= '0';
if state = DATA then
-- In single mode, we always enable MOSI, otherwise
-- we control the output enable based on the direction
-- of transfer.
--
if i = 0 and (data_single(cmd_mode) or data_write(cmd_mode)) then
sdat_oe(i) <= '1';
end if;
if i = 1 and data_dual(cmd_mode) and data_write(cmd_mode) then
sdat_oe(i) <= '1';
end if;
if i > 0 and data_quad(cmd_mode) and data_write(cmd_mode) then
sdat_oe(i) <= '1';
end if;
end if;
end loop;
end process;

-- Latch input data no delay
input_delay_0: if INPUT_DELAY = 0 generate
process(clk)
begin
if rising_edge(clk) then
dat_i_l <= sdat_i;
end if;
end process;
end generate;

-- Latch input data half clock delay
input_delay_1: if INPUT_DELAY = 1 generate
process(clk)
begin
if falling_edge(clk) then
dat_i_l <= sdat_i;
end if;
end process;
end generate;

-- Shift input data
shift_in: process(clk)
begin
if rising_edge(clk) then

-- Delay the receive signal to match the input latch
if state = DATA then
sck_recv_d <= sck_recv;
else
sck_recv_d <= '0';
end if;

-- Generate read data acks
if bit_count = "000" and sck_recv = '1' then
dat_ack_l <= not cmd_mode(0);
else
dat_ack_l <= '0';
end if;

-- And delay them as well
d_ack_o <= dat_ack_l;

-- Shift register on delayed data & receive signal
if sck_recv_d = '1' then
if DATA_LINES = 1 then
ireg <= ireg(6 downto 0) & dat_i_l(0);
else
if data_dual(cmd_mode) then
ireg <= ireg(5 downto 0) & dat_i_l(1) & dat_i_l(0);
elsif data_quad(cmd_mode) then
ireg <= ireg(3 downto 0) & dat_i_l(3) & dat_i_l(2) & dat_i_l(1) & dat_i_l(0);
else
assert(data_single(cmd_mode));
ireg <= ireg(6 downto 0) & dat_i_l(1);
end if;
end if;
end if;
end if;
end process;

-- Data recieve register
d_rxd_o <= ireg;

end architecture;

@ -14,7 +14,9 @@ entity syscon is
HAS_DRAM : boolean;
BRAM_SIZE : integer;
DRAM_SIZE : integer;
DRAM_INIT_SIZE : integer
DRAM_INIT_SIZE : integer;
HAS_SPI_FLASH : boolean;
SPI_FLASH_OFFSET : integer
);
port (
clk : in std_ulogic;
@ -44,6 +46,7 @@ architecture behaviour of syscon is
constant SYS_REG_CLKINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "100";
constant SYS_REG_CTRL : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "101";
constant SYS_REG_DRAMINITINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "110";
constant SYS_REG_SPIFLASHINFO : std_ulogic_vector(SYS_REG_BITS-1 downto 0) := "111";

-- Muxed reg read signal
signal reg_out : std_ulogic_vector(63 downto 0);
@ -52,6 +55,7 @@ architecture behaviour of syscon is
constant SYS_REG_INFO_HAS_UART : integer := 0;
constant SYS_REG_INFO_HAS_DRAM : integer := 1;
constant SYS_REG_INFO_HAS_BRAM : integer := 2;
constant SYS_REG_INFO_HAS_SPIF : integer := 3;

-- BRAMINFO contains the BRAM size in the bottom 52 bits
-- DRAMINFO contains the DRAM size if any in the bottom 52 bits
@ -64,6 +68,12 @@ architecture behaviour of syscon is
constant SYS_REG_CTRL_CORE_RESET : integer := 1;
constant SYS_REG_CTRL_SOC_RESET : integer := 2;

-- SPI Info register bits
--
-- Top 32-bit is flash offset which is the amount of flash
-- reserved for the FPGA bitfile if any
constant SYS_REG_SPI_INFO_IS_FLASH : integer := 0;

-- Ctrl register
signal reg_ctrl : std_ulogic_vector(SYS_REG_CTRL_BITS-1 downto 0);
signal reg_ctrl_out : std_ulogic_vector(63 downto 0);
@ -74,10 +84,13 @@ architecture behaviour of syscon is
signal reg_draminfo : std_ulogic_vector(63 downto 0);
signal reg_dramiinfo : std_ulogic_vector(63 downto 0);
signal reg_clkinfo : std_ulogic_vector(63 downto 0);
signal reg_spiinfo : std_ulogic_vector(63 downto 0);
signal info_has_dram : std_ulogic;
signal info_has_bram : std_ulogic;
signal info_has_uart : std_ulogic;
signal info_has_spif : std_ulogic;
signal info_clk : std_ulogic_vector(39 downto 0);
signal info_fl_off : std_ulogic_vector(31 downto 0);
begin

-- Generated output signals
@ -93,10 +106,12 @@ begin
info_has_uart <= '1' when HAS_UART else '0';
info_has_dram <= '1' when HAS_DRAM else '0';
info_has_bram <= '1' when BRAM_SIZE /= 0 else '0';
info_has_spif <= '1' when HAS_SPI_FLASH else '0';
info_clk <= std_ulogic_vector(to_unsigned(CLK_FREQ, 40));
reg_info <= (0 => info_has_uart,
1 => info_has_dram,
2 => info_has_bram,
reg_info <= (SYS_REG_INFO_HAS_UART => info_has_uart,
SYS_REG_INFO_HAS_DRAM => info_has_dram,
SYS_REG_INFO_HAS_BRAM => info_has_bram,
SYS_REG_INFO_HAS_SPIF => info_has_spif,
others => '0');
reg_braminfo <= x"000" & std_ulogic_vector(to_unsigned(BRAM_SIZE, 52));
reg_draminfo <= x"000" & std_ulogic_vector(to_unsigned(DRAM_SIZE, 52)) when HAS_DRAM
@ -105,6 +120,9 @@ begin
else (others => '0');
reg_clkinfo <= (39 downto 0 => info_clk,
others => '0');
info_fl_off <= std_ulogic_vector(to_unsigned(SPI_FLASH_OFFSET, 32));
reg_spiinfo <= (31 downto 0 => info_fl_off,
others => '0');

-- Control register read composition
reg_ctrl_out <= (63 downto SYS_REG_CTRL_BITS => '0',
@ -119,6 +137,7 @@ begin
reg_dramiinfo when SYS_REG_DRAMINITINFO,
reg_clkinfo when SYS_REG_CLKINFO,
reg_ctrl_out when SYS_REG_CTRL,
reg_spiinfo when SYS_REG_SPIFLASHINFO,
(others => '0') when others;
wishbone_out.dat <= reg_out(63 downto 32) when wishbone_in.adr(2) = '1' else
reg_out(31 downto 0);

Loading…
Cancel
Save