Skip to content

Commit d68e394

Browse files
Increase espi register visibility
1 parent 9af73f3 commit d68e394

10 files changed

Lines changed: 270 additions & 29 deletions

File tree

hdl/ip/vhd/espi/BUCK

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ rdl_file(
1818
rdl_file(
1919
name = "espi_regs_rdl",
2020
src = "sys_regs/espi_regs.rdl",
21+
deps = [":espi_spec_regs_rdl"],
2122
outputs = ["espi_regs_pkg.vhd", "espi_regs.html", "espi_regs.json"],
2223
visibility = ['PUBLIC']
2324
)

hdl/ip/vhd/espi/espi_spec_regs.vhd

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use ieee.std_logic_1164.all;
1515
use ieee.numeric_std.all;
1616
use ieee.numeric_std_unsigned.all;
1717
use work.espi_spec_regs_pkg.all;
18+
use work.espi_spec_regs_view_pkg.all;
1819
use work.link_layer_pkg.all;
1920
use work.espi_base_types_pkg.all;
2021

@@ -26,6 +27,9 @@ entity espi_spec_regs is
2627
regs_if : view regs_side;
2728
espi_reset : in std_logic;
2829

30+
-- Read-only view of all spec registers for the sys_regs block
31+
spec_regs_view : view spec_regs_source;
32+
2933
qspi_mode : out qspi_mode_t;
3034
wait_states : out std_logic_vector(3 downto 0);
3135
oob_enabled : out std_logic;
@@ -41,6 +45,7 @@ architecture rtl of espi_spec_regs is
4145
signal ch1_capabilities : ch1_capabilities_type;
4246
signal ch2_capabilities : ch2_capabilities_type;
4347
signal ch3_capabilities : ch3_capabilities_type;
48+
constant ch3_capabilities2 : ch3_capabilities2_type := rec_reset;
4449
signal readdata_valid : std_logic;
4550
signal readdata : std_logic_vector(31 downto 0);
4651
signal qspi_freq : qspi_freq_t;
@@ -53,6 +58,15 @@ begin
5358

5459
flash_channel_enable <= ch3_capabilities.flash_channel_enable = '1';
5560
oob_enabled <= ch2_capabilities.chan_en;
61+
62+
spec_regs_view.device_id <= device_id;
63+
spec_regs_view.general_capabilities <= gen_capabilities;
64+
spec_regs_view.ch0_capabilities <= ch0_capabilities;
65+
spec_regs_view.ch1_capabilities <= ch1_capabilities;
66+
spec_regs_view.ch2_capabilities <= ch2_capabilities;
67+
spec_regs_view.ch3_capabilities <= ch3_capabilities;
68+
spec_regs_view.ch3_capabilities2 <= ch3_capabilities2;
69+
5670
-- Write-side of the spec-defined registers
5771
write_reg: process(clk, reset)
5872
begin

hdl/ip/vhd/espi/espi_target_top.vhd

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use ieee.numeric_std.all;
1414
use ieee.numeric_std_unsigned.all;
1515
use work.qspi_link_layer_pkg.all;
1616
use work.espi_base_types_pkg.all;
17+
use work.espi_spec_regs_view_pkg.all;
1718
use work.flash_channel_pkg.all;
1819
use work.uart_channel_pkg.all;
1920
use work.link_layer_pkg.all;
@@ -68,6 +69,7 @@ architecture rtl of espi_target_top is
6869
signal flash_c_avail : std_logic;
6970
signal flash_channel_enable : boolean;
7071
signal dbg_chan : dbg_chan_t;
72+
signal spec_regs : spec_regs_t;
7173
signal response_done : boolean;
7274
signal pc_free : std_logic;
7375
signal pc_avail : std_logic;
@@ -107,6 +109,10 @@ architecture rtl of espi_target_top is
107109
signal oob_enabled : std_logic;
108110
signal stuff_fifo : std_logic;
109111
signal stuff_wds : std_logic_vector(15 downto 0);
112+
signal last_resp_status : std_logic_vector(15 downto 0);
113+
signal host_to_sp_fifo_usedwds : std_logic_vector(12 downto 0);
114+
signal oob_free_saw_full : std_logic;
115+
signal live_espi_status : std_logic_vector(15 downto 0);
110116

111117
begin
112118

@@ -254,11 +260,16 @@ begin
254260
stuff_fifo => stuff_fifo,
255261
stuff_wds => stuff_wds,
256262
dbg_chan => dbg_chan,
263+
spec_regs_view => spec_regs,
257264
post_code => post_code,
258265
post_code_valid => post_code_valid,
259266
espi_reset => espi_reset_strobe_syncd,
260267
to_host_tx_fifo_usedwds => to_host_tx_fifo_usedwds,
261-
ipcc_to_host_byte_cntr => ipcc_to_host_byte_cntr
268+
ipcc_to_host_byte_cntr => ipcc_to_host_byte_cntr,
269+
live_espi_status => live_espi_status,
270+
last_resp_status => last_resp_status,
271+
host_to_sp_fifo_usedwds => host_to_sp_fifo_usedwds,
272+
oob_free_saw_full => oob_free_saw_full
262273
);
263274

264275
-- txn layer blocks
@@ -292,7 +303,9 @@ begin
292303
np_avail => np_avail,
293304
oob_free => oob_free,
294305
oob_avail => oob_avail,
295-
vwire_avail => vwire_avail
306+
vwire_avail => vwire_avail,
307+
live_espi_status => live_espi_status,
308+
last_resp_status => last_resp_status
296309
);
297310

298311
-- espi-internal register block
@@ -302,6 +315,7 @@ begin
302315
reset => reset,
303316
espi_reset => espi_reset_strobe_syncd,
304317
regs_if => regs_if,
318+
spec_regs_view => spec_regs,
305319
qspi_mode => qspi_mode,
306320
wait_states => wait_states_slow,
307321
flash_channel_enable => flash_channel_enable,
@@ -350,7 +364,9 @@ begin
350364
oob_avail => oob_avail,
351365
oob_free => oob_free,
352366
to_host_tx_fifo_usedwds => to_host_tx_fifo_usedwds,
353-
ipcc_to_host_byte_cntr => ipcc_to_host_byte_cntr
367+
ipcc_to_host_byte_cntr => ipcc_to_host_byte_cntr,
368+
host_to_sp_fifo_usedwds => host_to_sp_fifo_usedwds,
369+
oob_free_saw_full => oob_free_saw_full
354370
);
355371

356372
-- vwire channel logic

hdl/ip/vhd/espi/peripheral_channel/uart_channel_top.vhd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ entity uart_channel_top is
5555
np_avail: out std_logic;
5656
to_host_tx_fifo_usedwds : out std_logic_vector(log2ceil(fifo_depth) downto 0);
5757
ipcc_to_host_byte_cntr : out std_logic_vector(31 downto 0);
58+
host_to_sp_fifo_usedwds : out std_logic_vector(log2ceil(fifo_depth) downto 0);
59+
-- Sticky: set when oob_free goes low, cleared only by espi_reset
60+
oob_free_saw_full : out std_logic
5861
);
5962

6063
end entity;
@@ -84,6 +87,7 @@ architecture rtl of uart_channel_top is
8487
begin
8588

8689
to_host_tx_fifo_usedwds <= tx_rusedwds;
90+
host_to_sp_fifo_usedwds <= rx_wusedwds;
8791

8892
-- Not going to support any Non-posted transactions
8993
-- on this interface
@@ -209,6 +213,20 @@ begin
209213
end if;
210214
end process;
211215

216+
-- Sticky detector: captures if oob_free ever went low since last espi_reset
217+
oob_free_sticky: process(clk, reset)
218+
begin
219+
if reset then
220+
oob_free_saw_full <= '0';
221+
elsif rising_edge(clk) then
222+
if espi_reset then
223+
oob_free_saw_full <= '0';
224+
elsif oob_free = '0' and enabled = '1' then
225+
oob_free_saw_full <= '1';
226+
end if;
227+
end if;
228+
end process;
229+
212230
from_host_rx_fifo: entity work.dcfifo_xpm
213231
generic map(
214232
fifo_write_depth => fifo_depth,

hdl/ip/vhd/espi/sims/espi_tb.vhd

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ use work.qspi_vc_pkg.all;
1818
use work.espi_controller_vc_pkg.all;
1919
use work.espi_base_types_pkg.all;
2020
use work.espi_spec_regs_pkg.all;
21+
use work.espi_regs_pkg;
2122
use work.espi_dbg_vc_pkg.all;
2223
use work.espi_tb_pkg.all;
2324

24-
use work.espi_regs_pkg.all;
2525
entity espi_tb is
2626
generic (
2727

@@ -105,15 +105,15 @@ begin
105105
check_equal(response.status, expected_status, "Status did not match reset value");
106106
exp_data_32 := (others => '0');
107107
-- Should have an empty response queue
108-
read_bus(net, bus_handle, To_StdLogicVector(STATUS_OFFSET, bus_handle.p_address_length), data_32);
108+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.STATUS_OFFSET, bus_handle.p_address_length), data_32);
109109
check_equal(data_32, exp_data_32, "Response queue not empty before bad crc command");
110110

111111
-- Issue a command with a bad CRC
112112
dbg_send_get_status_cmd(net, bad_crc => true);
113113
dbg_wait_for_done(net);
114114
wait for 1 us;
115115
-- Expect no responses
116-
read_bus(net, bus_handle, To_StdLogicVector(FIFO_STATUS_OFFSET, bus_handle.p_address_length), data_32);
116+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.FIFO_STATUS_OFFSET, bus_handle.p_address_length), data_32);
117117
exp_data_32 := (others => '0');
118118
check_equal(data_32, exp_data_32, "Expected no response to bad CRC command");
119119

@@ -250,19 +250,19 @@ begin
250250
-- verify counts are correct.
251251
wait for 1 us;
252252
-- Check *last* post code register
253-
read_bus(net, bus_handle, To_StdLogicVector(LAST_POST_CODE_OFFSET, bus_handle.p_address_length), data_32);
253+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.LAST_POST_CODE_OFFSET, bus_handle.p_address_length), data_32);
254254
check_equal(data_32, exp_data_32, "Single post code register readback failed");
255255
-- Check post code buffer entry 0
256-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_BUFFER_OFFSET, bus_handle.p_address_length), data_32);
256+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_BUFFER_OFFSET, bus_handle.p_address_length), data_32);
257257
check_equal(data_32, exp_data_32, "Post code buffer readback failed");
258258
-- Check post code count register
259-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
259+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
260260
check_equal(data_32, std_logic_vector'(x"00000001"), "Post code count register readback failed");
261261

262262
-- issue an espi reset and verify post code count resets
263263
dbg_espi_reset(net);
264264
wait for 1 us;
265-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
265+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
266266
check_equal(data_32, std_logic_vector'(x"00000000"), "Post code count register did not reset after espi reset");
267267

268268

@@ -277,13 +277,13 @@ begin
277277
dbg_wait_for_done(net);
278278
wait for 1 us;
279279
-- Check *last* post code register
280-
read_bus(net, bus_handle, To_StdLogicVector(LAST_POST_CODE_OFFSET, bus_handle.p_address_length), data_32);
280+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.LAST_POST_CODE_OFFSET, bus_handle.p_address_length), data_32);
281281
check_equal(data_32, exp_data_32, "Single post code register readback failed");
282282
-- Check post code buffer entry 0
283-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_BUFFER_OFFSET, bus_handle.p_address_length), data_32);
283+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_BUFFER_OFFSET, bus_handle.p_address_length), data_32);
284284
check_equal(data_32, exp_data_32, "Post code buffer readback failed");
285285
-- Check post code count register
286-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
286+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
287287
check_equal(data_32, std_logic_vector'(x"00000001"), "Post code count register readback failed");
288288

289289
exp_data_32 := x"000101de";
@@ -293,21 +293,21 @@ begin
293293
wait for 1 us;
294294

295295
-- Check *last* post code register
296-
read_bus(net, bus_handle, To_StdLogicVector(LAST_POST_CODE_OFFSET, bus_handle.p_address_length), data_32);
296+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.LAST_POST_CODE_OFFSET, bus_handle.p_address_length), data_32);
297297
check_equal(data_32, exp_data_32, "Single post code register readback failed");
298298
-- Check post code buffer entry 0
299-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_BUFFER_OFFSET, bus_handle.p_address_length), data_32);
299+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_BUFFER_OFFSET, bus_handle.p_address_length), data_32);
300300
check_equal(data_32, std_logic_vector'(x"000001de"), "Post code buffer 0 readback failed");
301-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_BUFFER_OFFSET + 4, bus_handle.p_address_length), data_32);
301+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_BUFFER_OFFSET + 4, bus_handle.p_address_length), data_32);
302302
check_equal(data_32, exp_data_32, "Post code buffer 1 readback failed");
303303
-- Check post code count register
304-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
304+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
305305
check_equal(data_32, std_logic_vector'(x"00000002"), "Post code count register readback failed");
306306

307307
-- issue an espi reset and verify post code count resets
308308
dbg_espi_reset(net);
309309
wait for 1 us;
310-
read_bus(net, bus_handle, To_StdLogicVector(POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
310+
read_bus(net, bus_handle, To_StdLogicVector(espi_regs_pkg.POST_CODE_COUNT_OFFSET, bus_handle.p_address_length), data_32);
311311
check_equal(data_32, std_logic_vector'(x"00000000"), "Post code count register did not reset after espi reset");
312312

313313
elsif run("put_iowr_short") then

hdl/ip/vhd/espi/sys_regs/espi_regs.rdl

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,22 @@ addrmap espi_regs {
126126
} post_code_count;
127127

128128
reg {
129-
name = "IPCC_TO_HOST_USEDWDS";
129+
name = "IPCC_SP_TO_HOST_USEDWDS";
130130
desc = "Count of usedwds in the IPCC to host TX FIFO";
131131
field {
132132
desc = "";
133133
} count[31:0] = 0;
134134
} ipcc_to_host_usedwds;
135135

136+
reg {
137+
name = "IPCC_HOST_TO_SP_USEDWDS";
138+
desc = "Count of used words in the host-to-SP IPCC RX FIFO";
139+
field {
140+
default sw = r;
141+
desc = "";
142+
} count[31:0] = 0;
143+
} ipcc_host_to_sp_usedwds;
144+
136145
reg {
137146
name = "IPCC_TO_HOST_BYTE_CNTR";
138147
desc = "Count of total bytes sent to host via IPCC UART channel since reset";
@@ -157,6 +166,107 @@ addrmap espi_regs {
157166
} count[31:0] = 0;
158167
} ipcc_dummy_fill_count;
159168

169+
reg espi_status {
170+
field {
171+
desc = "When '1', indicates the target has a channel 3
172+
Flash Access non-posted header and data up to
173+
maximum payload size available to send.
174+
This bit is only applicable when controller
175+
attached flash sharing is supported and in
176+
operation. Otherwise, the bit is a don't care.";
177+
} FLASH_NP_AVAIL[13:13];
178+
field {
179+
desc = "When '1', indicates the target has a channel 3
180+
Flash Access completion header and data up to
181+
maximum payload size available to send.
182+
This bit is only applicable when target attached
183+
flash sharing is supported and in operation.
184+
Otherwise, the bit is a don't care.";
185+
} FLASH_C_AVAIL[12:12];
186+
field {
187+
desc = "When '1', indicates the target is free to accept
188+
at least one channel 3 Flash Access non-posted
189+
header and data up to maximum payload size.
190+
This bit is only applicable when target attached
191+
flash sharing is supported and in operation.
192+
Otherwise, the bit is a don't care.";
193+
} FLASH_NP_FREE[9:9];
194+
field {
195+
desc = "When '1', indicates the target is free to accept
196+
at least one channel 3 Flash Access completion
197+
header and data up to maximum payload size.
198+
This bit must be always a '1'. The target must
199+
be able to accept the completion for the non-
200+
posted request it sends.
201+
This bit is only applicable when controller
202+
attached flash sharing is supported and in
203+
operation. Otherwise, the bit is a don't care.";
204+
} FLASH_C_FREE[8:8];
205+
field {
206+
desc = "When '1', indicates the target has a channel 2
207+
OOB (tunneled SMBus) message with data up
208+
to maximum payload size available to send.";
209+
} OOB_AVAIL[7:7];
210+
field {
211+
desc = "When '1', indicates the target has a channel 1
212+
tunneled virtual wire available to send.";
213+
} VWIRE_AVAIL[6:6];
214+
field {
215+
desc = "When '1', indicates the target has a channel 0
216+
peripheral non-posted header available to
217+
send.";
218+
} NP_AVAIL[5:5];
219+
220+
field {
221+
desc = "When '1', indicates the target has a channel 0
222+
peripheral posted or completion header and
223+
optional data up to maximum payload size
224+
available to send.";
225+
} PC_AVAIL[4:4];
226+
227+
field {
228+
desc = "When '1', indicates the target is free to accept
229+
at least one channel 2 OOB (tunneled SMBus)
230+
message with data up to maximum payload size.";
231+
} OOB_FREE[3:3];
232+
field {
233+
desc = "This bit must be always a '1'. Tunneling of
234+
channel 1 virtual wires is not flow controlled.";
235+
} VWIRE_FREE[2:2];
236+
field {
237+
desc = "When '1', indicates the target is free to accept
238+
at least one channel 0 peripheral non-posted
239+
header and 1 DW of Data (if applicable).";
240+
} NP_FREE[1:1];
241+
field {
242+
desc = "When '1', indicates the target is free to accept
243+
at least one channel 0 peripheral posted or
244+
completion header and data up to maximum
245+
payload size.";
246+
} PC_FREE[0:0];
247+
248+
};
249+
250+
espi_status LIVE_ESPI_STATUS;
251+
LIVE_ESPI_STATUS->name = "LIVE_ESPI_STATUS";
252+
253+
espi_status LAST_RESP_STATUS;
254+
LAST_RESP_STATUS->name = "LAST_RESP_STATUS";
255+
256+
257+
reg {
258+
name = "OOB_FREE_SAW_FULL";
259+
desc = "Sticky bit: set to 1 if oob_free ever went low (RX FIFO nearly full) since last eSPI reset. Cleared only by eSPI reset.";
260+
field {
261+
default sw = r;
262+
desc = "";
263+
} saw_full[0:0] = 0;
264+
} oob_free_saw_full;
265+
266+
// Read-only view of the eSPI spec registers, so the SP can
267+
// observe what the eSPI host has configured.
268+
eSPI_Spec spec_regs @ 0x0080;
269+
160270
mem post_code_buffer_mem {
161271
mementries = 4096;
162272
memwidth = 32;

0 commit comments

Comments
 (0)