regnual: flash write support
This commit is contained in:
@@ -28,9 +28,16 @@
|
||||
#include "types.h"
|
||||
#include "usb_lld.h"
|
||||
|
||||
extern void set_led (int);
|
||||
extern void *memset (void *s, int c, size_t n);
|
||||
|
||||
extern void set_led (int);
|
||||
extern uint8_t _flash_start, _flash_end;
|
||||
extern int flash_write (uint32_t dst_addr, const uint8_t *src, size_t len);
|
||||
extern int flash_erase_page (uint32_t addr);
|
||||
extern int flash_protect (void);
|
||||
extern void nvic_system_reset (void);
|
||||
|
||||
|
||||
#define ENDP0_RXADDR (0x40)
|
||||
#define ENDP0_TXADDR (0x80)
|
||||
|
||||
@@ -81,24 +88,24 @@ static const uint8_t regnual_string_serial[] = {
|
||||
'0', 0, '.', 0, '0', 0,
|
||||
};
|
||||
|
||||
const struct Descriptor Device_Descriptor = {
|
||||
const struct Descriptor device_desc = {
|
||||
regnual_device_desc,
|
||||
sizeof (regnual_device_desc)
|
||||
};
|
||||
|
||||
const struct Descriptor Config_Descriptor = {
|
||||
const struct Descriptor config_desc = {
|
||||
regnual_config_desc,
|
||||
sizeof (regnual_config_desc)
|
||||
};
|
||||
|
||||
const struct Descriptor String_Descriptors[] = {
|
||||
const struct Descriptor string_descs[] = {
|
||||
{regnual_string_lang_id, sizeof (regnual_string_lang_id)},
|
||||
{gnukStringVendor, sizeof (gnukStringVendor)},
|
||||
{gnukStringProduct, sizeof (gnukStringProduct)},
|
||||
{regnual_string_serial, sizeof (regnual_string_serial)},
|
||||
};
|
||||
|
||||
#define NUM_STRING_DESC (sizeof (String_Descriptors)/sizeof (struct Descriptor))
|
||||
#define NUM_STRING_DESC (sizeof (string_descs)/sizeof (struct Descriptor))
|
||||
|
||||
static void
|
||||
regnual_device_reset (void)
|
||||
@@ -107,7 +114,7 @@ regnual_device_reset (void)
|
||||
usb_lld_set_configuration (0);
|
||||
|
||||
/* Current Feature initialization */
|
||||
usb_lld_set_feature (Config_Descriptor.Descriptor[7]);
|
||||
usb_lld_set_feature (config_desc.Descriptor[7]);
|
||||
|
||||
usb_lld_reset ();
|
||||
|
||||
@@ -124,7 +131,10 @@ regnual_device_reset (void)
|
||||
#define USB_REGNUAL_PROTECT 5
|
||||
#define USB_REGNUAL_FINISH 6
|
||||
|
||||
static uint8_t mem[1024];
|
||||
static uint8_t mem[256];
|
||||
|
||||
static const uint8_t *const mem_info[] = { &_flash_start, &_flash_end, };
|
||||
|
||||
|
||||
static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index,
|
||||
@@ -133,16 +143,13 @@ static void regnual_ctrl_write_finish (uint8_t req, uint8_t req_no,
|
||||
uint8_t type_rcp = req & (REQUEST_TYPE|RECIPIENT);
|
||||
|
||||
if (type_rcp == (VENDOR_REQUEST | DEVICE_RECIPIENT)
|
||||
&& USB_SETUP_SET (req) && req_no == USB_REGNUAL_FINISH && len == 0)
|
||||
&& USB_SETUP_SET (req) && len == 0)
|
||||
{
|
||||
(void)value; (void)index;
|
||||
/* RESET MCU */
|
||||
}
|
||||
if (req_no == USB_REGNUAL_FINISH && value == 0 && index == 0)
|
||||
nvic_system_reset ();
|
||||
}
|
||||
}
|
||||
|
||||
extern uint8_t _flash_start, _flash_end;
|
||||
static const uint8_t *const mem_info[] = { &_flash_start, &_flash_end, };
|
||||
|
||||
static int
|
||||
regnual_setup (uint8_t req, uint8_t req_no,
|
||||
uint16_t value, uint16_t index, uint16_t len)
|
||||
@@ -170,21 +177,38 @@ regnual_setup (uint8_t req, uint8_t req_no,
|
||||
{
|
||||
if (req_no == USB_REGNUAL_SEND)
|
||||
{
|
||||
if (value >= 4 || value * 0x100 + index + len > 1024)
|
||||
if (value != 0 || index + len > 256)
|
||||
return USB_UNSUPPORT;
|
||||
|
||||
if (value == 0 && index == 0)
|
||||
memset (mem + value * 0x100, 0xff, 1024);
|
||||
usb_lld_set_data_to_recv (mem + value * 0x100 + index, len);
|
||||
if (index != 0)
|
||||
memset (mem, 0xff, 256);
|
||||
|
||||
usb_lld_set_data_to_recv (mem + index, len);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_FLASH && len == 0)
|
||||
{
|
||||
uint8_t *addr = (uint8_t *)(0x08000000 + value * 0x400);
|
||||
uint32_t dst_addr = (0x08000000 + value * 0x100);
|
||||
|
||||
/* flash write, verify */
|
||||
return USB_SUCCESS;
|
||||
if (flash_write (dst_addr, mem, 256) == 0)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_ERASE && len == 0 && index == 0)
|
||||
{
|
||||
uint32_t dst_addr = (0x08000000 + value * 0x100);
|
||||
|
||||
if (flash_erase_page (dst_addr))
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_PROTECT && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
{
|
||||
if (flash_protect ())
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (req_no == USB_REGNUAL_FINISH && len == 0
|
||||
&& value == 0 && index == 0)
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,14 +221,14 @@ regnual_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
|
||||
(void)index;
|
||||
if (desc_type == DEVICE_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (Device_Descriptor.Descriptor,
|
||||
Device_Descriptor.Descriptor_Size);
|
||||
usb_lld_set_data_to_send (device_desc.Descriptor,
|
||||
device_desc.Descriptor_Size);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (desc_type == CONFIG_DESCRIPTOR)
|
||||
{
|
||||
usb_lld_set_data_to_send (Config_Descriptor.Descriptor,
|
||||
Config_Descriptor.Descriptor_Size);
|
||||
usb_lld_set_data_to_send (config_desc.Descriptor,
|
||||
config_desc.Descriptor_Size);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
else if (desc_type == STRING_DESCRIPTOR)
|
||||
@@ -213,8 +237,8 @@ regnual_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
|
||||
|
||||
if (desc_index < NUM_STRING_DESC)
|
||||
{
|
||||
usb_lld_set_data_to_send (String_Descriptors[desc_index].Descriptor,
|
||||
String_Descriptors[desc_index].Descriptor_Size);
|
||||
usb_lld_set_data_to_send (string_descs[desc_index].Descriptor,
|
||||
string_descs[desc_index].Descriptor_Size);
|
||||
return USB_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,59 @@ def iso7816_compose(ins, p1, p2, data):
|
||||
else:
|
||||
return pack('>BBBBB', cls, ins, p1, p2, data_len) + data
|
||||
|
||||
class regnual:
|
||||
def __init__(self, device):
|
||||
self.__devhandle = device.open()
|
||||
|
||||
def mem_info(self):
|
||||
mem = self.__devhandle.controlMsg(requestType = 0xc0, request = 0,
|
||||
value = 0, index = 0, buffer = 8,
|
||||
timeout = 10000)
|
||||
start = ((mem[3]*256 + mem[2])*256 + mem[1])*256 + mem[0]
|
||||
end = ((mem[7]*256 + mem[6])*256 + mem[5])*256 + mem[4]
|
||||
return (start, end)
|
||||
|
||||
def download(self, start, data):
|
||||
addr = start
|
||||
addr_end = (start + len(data)) & 0xffffff00
|
||||
i = (addr - 0x08000000) / 0x100
|
||||
j = 0
|
||||
print "start %08x" % addr
|
||||
print "end %08x" % addr_end
|
||||
while addr < addr_end:
|
||||
print "# %08x: %d: %d : %d" % (addr, i, j, 256)
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
|
||||
value = 0, index = 0,
|
||||
buffer = data[j*256:j*256+256],
|
||||
timeout = 10000)
|
||||
print "flash"
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 3,
|
||||
value = i, index = 0,
|
||||
buffer = None,
|
||||
timeout = 10000)
|
||||
i = i+1
|
||||
j = j+1
|
||||
addr = addr + 256
|
||||
residue = len(data) % 256
|
||||
if residue != 0:
|
||||
print "# %08x: %d : %d" % (addr, i, residue)
|
||||
print "send"
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 1,
|
||||
value = 0, index = 0,
|
||||
buffer = data[j*256:],
|
||||
timeout = 10000)
|
||||
if (i % 4) != 0 or residue:
|
||||
print "flash"
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 3,
|
||||
value = i, index = 0,
|
||||
buffer = None,
|
||||
timeout = 10000)
|
||||
|
||||
def finish(self):
|
||||
self.__devhandle.controlMsg(requestType = 0x40, request = 6,
|
||||
value = 0, index = 0, buffer = None,
|
||||
timeout = 10000)
|
||||
|
||||
# This class only supports Gnuk (for now)
|
||||
class gnuk_token:
|
||||
def __init__(self, device, configuration, interface):
|
||||
@@ -80,9 +133,9 @@ class gnuk_token:
|
||||
self.__timeout = 10000
|
||||
self.__seq = 0
|
||||
|
||||
def stop_icc(self):
|
||||
# XXX: need to disclaim interface and close device and re-open???
|
||||
# self.__devhandle.setConfiguration(0)
|
||||
def stop_gnuk(self):
|
||||
self.__devhandle.releaseInterface()
|
||||
self.__devhandle.setConfiguration(0)
|
||||
return
|
||||
|
||||
def mem_info(self):
|
||||
@@ -237,7 +290,7 @@ def compare(data_original, data_in_device):
|
||||
raise ValueError, "verify failed at %08x" % i
|
||||
i += 1
|
||||
|
||||
def get_device():
|
||||
def get_ccid_device():
|
||||
busses = usb.busses()
|
||||
for bus in busses:
|
||||
devices = bus.devices
|
||||
@@ -251,6 +304,21 @@ def get_device():
|
||||
return dev, config, alt
|
||||
raise ValueError, "Device not found"
|
||||
|
||||
USB_VENDOR_FSIJ=0x234b
|
||||
USB_PRODUCT_GNUK=0x0000
|
||||
|
||||
def get_gnuk_device():
|
||||
busses = usb.busses()
|
||||
for bus in busses:
|
||||
devices = bus.devices
|
||||
for dev in devices:
|
||||
if dev.idVendor != USB_VENDOR_FSIJ:
|
||||
continue
|
||||
if dev.idProduct != USB_PRODUCT_GNUK:
|
||||
continue
|
||||
return dev
|
||||
raise ValueError, "Device not found"
|
||||
|
||||
def to_string(t):
|
||||
result = ""
|
||||
for c in t:
|
||||
@@ -260,7 +328,7 @@ def to_string(t):
|
||||
def main(passwd, data_regnual, data_upgrade):
|
||||
data_regnual += pack('<i', binascii.crc32(data_regnual))
|
||||
|
||||
dev, config, intf = get_device()
|
||||
dev, config, intf = get_ccid_device()
|
||||
print "Device: ", dev.filename
|
||||
print "Configuration: ", config.value
|
||||
print "Interface: ", intf.interfaceNumber
|
||||
@@ -274,15 +342,27 @@ def main(passwd, data_regnual, data_upgrade):
|
||||
challenge = icc.cmd_get_challenge()
|
||||
signed = to_string(challenge)
|
||||
icc.cmd_external_authenticate(signed)
|
||||
icc.stop_icc() # disable all interfaces but control pipe
|
||||
icc.stop_gnuk()
|
||||
mem_info = icc.mem_info()
|
||||
print "%08x:%08x" % mem_info
|
||||
print "Downloading flash upgrade program..."
|
||||
icc.download(mem_info[0], data_regnual)
|
||||
print "Run flash upgrade program..."
|
||||
icc.execute(mem_info[1] + len(data_regnual))
|
||||
del icc
|
||||
icc = None
|
||||
#
|
||||
print "Wait 3 seconds..."
|
||||
time.sleep(3)
|
||||
# Then, send upgrade program...
|
||||
print "NOT YET: Downloading the program"
|
||||
dev = get_gnuk_device()
|
||||
print "Device: ", dev.filename
|
||||
reg = regnual(dev)
|
||||
mem_info = reg.mem_info()
|
||||
print "%08x:%08x" % mem_info
|
||||
print "Downloading the program"
|
||||
reg.download(mem_info[0]+0x3000, data_upgrade)
|
||||
reg.finish()
|
||||
return 0
|
||||
|
||||
DEFAULT_PW3 = "12345678"
|
||||
|
||||
Reference in New Issue
Block a user