📄 ms.c
字号:
trace1(0, ms, 0, "ms_pio_read_page():%d", g_ms_page);
//_stack_check();
if (k_success != ms_write_parm_reg(0x80, 0x20))
return k_error;
if (k_success != ms_set_cmd(k_ms_block_read))
return k_error;
if (k_success != ms_get_int(5))
return k_error;
if (_factor & kbm_ms_reg_int_cmdnk)
{
trace0(0, err, 110, "error: cmdnk (ms_pio_read_page)");
return k_error;
}
if (!(_factor & kbm_ms_reg_int_ced))
{
trace0(0, err, 110, "error: ced not set (ms_pio_read_page)");
return k_error;
}
if (_factor & kbm_ms_reg_int_breq)
{
trace0(0, ms, 110, "breq (ms_pio_read_page)");
if (_factor & kbm_ms_reg_int_err)
{
trace0(0, err, 110, "error: err (ms_pio_read_page)");
if (k_success != ms_read_status())
return k_error;
// if ((_status1 & (kbm_ms_reg_status1_ucdt |kbm_ms_reg_status1_ucex |kbm_ms_reg_status1_ucfg)) ==
// (kbm_ms_reg_status1_ucdt |kbm_ms_reg_status1_ucex |kbm_ms_reg_status1_ucfg))
if (_status1 & (kbm_ms_reg_status1_ucdt |kbm_ms_reg_status1_ucex |kbm_ms_reg_status1_ucfg))
{
trace0(0, err, 110, "error: ucdt&ucex&ucfg - uncorrectable flash read error (ms_pio_read_page)");
ms_media_set_phyblock_failed();
return k_error;
}
}
if (k_success != ms_read_extra_data_reg())
return k_error;
if (k_success != ms_read_page_data(pnr))
return k_error;
return k_success;
}
trace0(0, err, 110, "error: unrecognized interrupt factor (ms_pio_read_page)");
return k_error;
}
//------------------------------------------------------------------------------
// Name:
// ms_write_all_reg
//
// Declaration:
// t_result ms_write_all_reg(uint8 sys_parm, uint8 cmd_parm);
//
// Purpose:
// Write the all of the of the MS card in preparation for issuing a
// write flash command. Writes the address, sys_parm, cmd_parm, page,
// and extra data.
//
// Arguments:
// sys_parm - specific to the flash command about to be issued.
// cmd_parm - specific to the flash command about to be issued.
//
// The following global variables are accessed and delivered to the MS card:
// g_ms_blk_addr_msb
// g_ms_blk_addr_mid
// g_ms_blk_addr_lsb
// g_ms_page
// g_ms_extra
//
// Return:
// A t_result indicating:
// k_success - parameter registers are written.
// k_error - failed write parameter registers. actual contents unknown.
//
// Notes:
// This is a FUNCTION, not a DFA.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result ms_write_all_reg(uint8 sys_parm,
uint8 cmd_parm) reentrant;
t_result ms_write_all_reg(uint8 sys_parm,
uint8 cmd_parm) reentrant
{
trace0(0, ms, 0, "ms_write_all_reg()");
//_stack_check();
trace3(0, ms, 10, " addr:0x00%02X%02X%02X", g_ms_blk_addr_msb, g_ms_blk_addr_mid, g_ms_blk_addr_lsb);
trace3(0, ms, 10, " page:0x%02X sys_parm:0x%02X cmd_parm:0x%02X", g_ms_page, sys_parm, cmd_parm);
if (k_success != ms_set_write_reg_addrs(k_ms_parm_system, 10))
return k_error;
// write the tpc
if (k_success != ms_set_tpc(k_ms_tpc_wr_reg, 10))
return k_error;
// write the parm regs
_ms_register_wr(ms_tx_db_msb, g_ms_blk_addr_msb);
_ms_register_wr(ms_tx_db_lsb, sys_parm);
if (!_ms_tx_data_fifo_is_empty())
if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
return k_error;
_ms_register_wr(ms_tx_db_msb, g_ms_blk_addr_lsb);
_ms_register_wr(ms_tx_db_lsb, g_ms_blk_addr_mid);
if (!_ms_tx_data_fifo_is_empty())
if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
return k_error;
_ms_register_wr(ms_tx_db_msb, g_ms_page);
_ms_register_wr(ms_tx_db_lsb, cmd_parm);
if (!_ms_tx_data_fifo_is_empty())
if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
return k_error;
// write the extra data
trace4(0, ms, 10, "wr xtra[0..3]:%02X%02X%02X%02X", g_ms_extra[0], g_ms_extra[1], g_ms_extra[2], g_ms_extra[3]);
_ms_register_wr(ms_tx_db_msb, g_ms_extra[1]);
_ms_register_wr(ms_tx_db_lsb, g_ms_extra[0]);
if (!_ms_tx_data_fifo_is_empty())
if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
return k_error;
_ms_register_wr(ms_tx_db_msb, g_ms_extra[3]);
_ms_register_wr(ms_tx_db_lsb, g_ms_extra[2]);
if (!_ms_tx_data_fifo_is_empty())
if (k_success != ms_wait_fifo_with_timeout(ms_fifo_stat_t_buf_e, ms_fifo_stat_t_buf_e, 3))
return k_error;
return k_success;
}
//+-----------------------------------------------------------------------------
// Name:
// ms_write_extra_data
//
// Declaration:
// t_result ms_write_extra_data(void);
//
// Purpose:
// Write the extra data registers of the active block of the MS card from
// the global variable g_ms_extra.
//
// Arguments:
// None.
//
// Return:
// A t_result indicating:
// k_success - contents of the global variable g_ms_extra written to card.
// k_error - cannot write the extra data.
//
// Notes:
// This is a FUNCTION, not a DFA.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result ms_write_extra_data(void) reentrant;
t_result ms_write_extra_data() reentrant
{
trace4(0, ms, 0, "ms_write_extra_data(addr:0x00%02X%02X%02X page:%d)", g_ms_blk_addr_msb, g_ms_blk_addr_mid, g_ms_blk_addr_lsb, g_ms_page);
//_stack_check();
if (k_success != ms_write_all_reg(0x80, 0x40))
return k_error;
if (k_success != ms_set_cmd(k_ms_block_write))
return k_error;
if (k_success != ms_get_int(10))
return k_error;
if (_factor & kbm_ms_reg_int_cmdnk)
{
trace0(0, err, 110, "error: cmdnk (ms_write_extra_data)");
return k_error;
}
if (!(_factor & kbm_ms_reg_int_ced))
{
trace0(0, err, 110, "error: ced not set (ms_write_extra_data)");
return k_error;
}
if (_factor & kbm_ms_reg_int_err)
{
trace0(0, err, 110, "error: !ced&err (ms_write_extra_data)");
return k_error;
}
return k_success;
}
//+-----------------------------------------------------------------------------
// Name:
// ms_erase_block
//
// Declaration:
// t_result ms_erase_block(void);
//
// Purpose:
// Erase he active block in the MS card.
//
// Arguments:
// None.
//
// Return:
// A t_result indicating:
// k_success - block is erased.
// k_error - cannot erase block. contents undefined.
//
// Notes:
// This is a FUNCTION, not a DFA.
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result ms_erase_block() reentrant
{
//_profile_on(7);
trace0(0, ms, 80, "ms_erase_block()");
//_stack_check();
//_profile_on(6);
if (k_success != ms_write_parm_reg(0x80, 0x00))
return k_error;
//_profile_off(6);
//_profile_on(5);
if (k_success != ms_set_cmd(k_ms_block_erase))
return k_error;
//_profile_off(5);
//_profile_on(4);
if (k_success != ms_get_int(100))
return k_error;
//_profile_off(4);
if (_factor & kbm_ms_reg_int_cmdnk)
{
trace0(0, err, 110, "error: cmdnk (ms_erase_block)");
return k_error;
}
if (!(_factor & kbm_ms_reg_int_ced))
{
trace0(0, err, 110, "error: ced not set (ms_erase_block)");
return k_error;
}
if (_factor & kbm_ms_reg_int_err)
{
trace0(0, err, 110, "error: err (ms_erase_block)");
return k_error;
}
//_profile_off(7);
return k_success;
}
//------------------------------------------------------------------------------
// steal a buffer from media.c temporarily (its ok, media.c only uses it for copy-sector).
// actually now that copy sector is done via fmc its probably not used for that purpose
// on the other luns anymore either.
//------------------------------------------------------------------------------
extern xdata uint8 g_sector_buffer[];
void xbuf_rd(uint16 offset, uint16 len, t_memory_ref bufp) reentrant
{
t_xdata_ref srcbufp;
mcu_begin_critical_section();
trace0(0, hal, 0, "mmu_rd()");
srcbufp = g_sector_buffer; // shouldnt this be _media_data(sector_buffer) ???
srcbufp += offset;
for (; len; len--, *bufp++=*srcbufp++);
mcu_end_critical_section();
}
//+-----------------------------------------------------------------------------
// Name:
// ms_read_boot_block
//
// Declaration:
// t_result ms_read_boot_block(void);
//
// Purpose:
// Determine the parameters (capacity etc) of the card by examining the contents
// of the boot block. Configures the _media_data() settings for the media based
// of the contents of the boot block.
//
// Arguments:
// None.
//
// Return:
// A t_result indicating:
// k_success - boot block read, _media_data() configured.
// k_error - cannot read boot block. contents of _media_data() undefined.
//
// Notes:
// This is a FUNCTION, not a DFA.
//
// Boot Block Format:
// page 0: header (368 bytes)
// system entry (48 bytes)
// boot and attribute info (96 bytes)
// page 1: disabled block data
// page 2: card info struct (256 byets)
// identification info (256 bytes)
//
// Since:
// fmc-1.0
//------------------------------------------------------------------------------
t_result ms_read_boot_block(void) reentrant;
t_result ms_read_boot_block() reentrant
{
uint8 blk;
//uint8 pnr;
uint8 boot_count;
t_result rslt;
trace0(0, ms, 80, "ms_read_boot_block()");
_force_one_burst_per_split = k_no; // br308
//_stack_check();
//pnr = mmu_allocate();
// no media/mapper optimizations at this time
_media_data(options) = kbm_media_data_opt_none;
_media_data(sector_buffer) = g_sector_buffer; // sneakily share media.c's buffer
boot_count = 0;
_media_data(boot_block) = 0xFF;
for (blk=0; blk<11; blk++)
{
trace1(0, ms, 80, "checking block %d", blk);
// read page 0 of the block
g_ms_blk_addr_msb = 0;
g_ms_blk_addr_mid = 0;
g_ms_blk_addr_lsb = blk;
g_ms_page = 0;
if (k_success != (rslt = ms_pio_read_page(k_max_pnr)))
{
trace0(0, err, 80, "error: cant read page zero of this block");
continue;
//goto exit;
}
// block status must be set; e.g., 'ok'
if (!(g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_bkst))
{
trace2(0, ms, 80, "blk:%d bkst:%02X", blk, g_ms_extra[k_ovwr_flg_offset] & kbm_ms_ext_ovwr_bkst);
continue;
}
// system bit must be clear; e.g., 'boot'
if (g_ms_extra[k_mgmt_flg_offset] & kbm_ms_ext_mgmt_sysflg)
{
trace2(0, ms, 80, "blk:%d sysflg:%02X", blk, g_ms_extra[k_mgmt_flg_offset] & kbm_ms_ext_mgmt_sysflg);
continue;
}
// top word of page 0 must be 0x0001
xbuf_rd(0, 2, (uint8*)&g_wtmp);
if (0x0001 != g_wtmp)
{
trace2(0, ms, 80, "blk:%d top word:%04X", blk, g_wtmp);
//dbg_dumpram(k_pkt_addrlo[pnr], k_pkt_addrhi[pnr], 512);
continue;
}
// found the boot block
boot_count++;
trace1(0, ms, 80, "BOOT BLOCK:%d", blk);
if (_media_data(boot_block) == 0xFF)
{
// if more than one boot block is found then choose the lowest numbered
trace0(0, ms, 80, "INSTALLING BOOT BLOCK INTO TABLE");
_media_data(boot_block) = blk;
}
trace1(0, ms, 80, "BOOT AREA MAX BLK NOW:%d", blk);
g_ms_user_area_start_blk=blk+1;
trace0(0, ms, 80, "PAGE 0 (HEADER)");
// block size?
xbuf_rd(418, 1, &(_ms_byte_per_block.u8.hi));
xbuf_rd(419, 1, &(_ms_byte_per_block.u8.lo));
_ms_byte_per_block.u16 *= 1024;
trace1(0, ms, 80, "_ms_byte_per_block:%d", _ms_byte_per_block.u16);
// number of blocks?
xbuf_rd(420, 1, &(_ms_block_per_card.u8.hi));
xbuf_rd(421, 1, &(_ms_block_per_card.u8.lo));
trace1(0, ms, 80, "_ms_block_per_card:%d", _ms_block_per_card.u16);
_media_data(num_zones) = _ms_block_per_card.u16 / k_phy_block_per_segment;
trace1(0, ms, 80, "_ms_zone_per_card:%d", _media_data(num_zones));
_media_data(physical_blocks_per_zone) = k_phy_block_per_segment;
_media_data(logical_blocks_per_zone) = k_log_block_per_segment;
_media_data(logical_blocks_per_boot_zone) = k_log_block_per_boot_segment;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -