mirror of
git://projects.qi-hardware.com/xburst-tools.git
synced 2024-11-26 03:04:04 +02:00
Implemented memory test
This commit is contained in:
commit
441e9d8a1f
51
ingenic.c
51
ingenic.c
@ -215,8 +215,6 @@ uint32_t ingenic_sdram_size(void *hndl) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int ingenic_address(void *usb, uint32_t base) {
|
static int ingenic_address(void *usb, uint32_t base) {
|
||||||
debug(LEVEL_DEBUG, "Ingenic: address 0x%08X\n", base);
|
|
||||||
|
|
||||||
return usbdev_vendor(usb, USBDEV_TODEV, VR_SET_DATA_ADDRESS, (base >> 16), base & 0xFFFF, 0, 0);
|
return usbdev_vendor(usb, USBDEV_TODEV, VR_SET_DATA_ADDRESS, (base >> 16), base & 0xFFFF, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,16 +283,12 @@ int ingenic_loadstage(void *hndl, int id, const char *file) {
|
|||||||
|
|
||||||
memcpy(data + 8, &handle->cfg, sizeof(firmware_config_t));
|
memcpy(data + 8, &handle->cfg, sizeof(firmware_config_t));
|
||||||
|
|
||||||
debug(LEVEL_DEBUG, "Ingenic: loading stage%d to 0x%08X, %d bytes\n", id, base, size);
|
|
||||||
|
|
||||||
if(ingenic_address(handle->usb, base) == -1) {
|
if(ingenic_address(handle->usb, base) == -1) {
|
||||||
free(data);
|
free(data);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hexdump(data, size);
|
|
||||||
|
|
||||||
int ret = usbdev_sendbulk(handle->usb, data, size);
|
int ret = usbdev_sendbulk(handle->usb, data, size);
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
@ -302,24 +296,55 @@ int ingenic_loadstage(void *hndl, int id, const char *file) {
|
|||||||
if(ret == -1)
|
if(ret == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
debug(LEVEL_DEBUG, "Ingenic: stage written\n");
|
|
||||||
|
|
||||||
if(id == INGENIC_STAGE2) {
|
if(id == INGENIC_STAGE2) {
|
||||||
debug(LEVEL_DEBUG, "Ingenic: flushing cache\n");
|
|
||||||
|
|
||||||
ret = usbdev_vendor(handle->usb, USBDEV_TODEV, VR_FLUSH_CACHES, 0, 0, 0, 0);
|
ret = usbdev_vendor(handle->usb, USBDEV_TODEV, VR_FLUSH_CACHES, 0, 0, 0, 0);
|
||||||
|
|
||||||
if(ret == -1)
|
if(ret == -1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(LEVEL_DEBUG, "Starting stage!\n");
|
|
||||||
|
|
||||||
ret = usbdev_vendor(handle->usb, USBDEV_TODEV, cmd, (base >> 16), base & 0xFFFF, 0, 0);
|
ret = usbdev_vendor(handle->usb, USBDEV_TODEV, cmd, (base >> 16), base & 0xFFFF, 0, 0);
|
||||||
|
|
||||||
if(ret == -1)
|
if(ret == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return ingenic_redetect(hndl);
|
if(id == INGENIC_STAGE2)
|
||||||
|
return ingenic_redetect(hndl);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ingenic_memtest(void *hndl, const char *filename, uint32_t base, uint32_t size, uint32_t *fail) {
|
||||||
|
HANDLE;
|
||||||
|
|
||||||
|
int ret = ingenic_stage1_debugop(handle, filename, STAGE1_DEBUG_MEMTEST, 0, base, size);
|
||||||
|
|
||||||
|
if(ret == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
uint32_t data[2];
|
||||||
|
|
||||||
|
ret = usbdev_recvbulk(handle->usb, &data, sizeof(data));
|
||||||
|
|
||||||
|
if(ret == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
hexdump(data, ret);
|
||||||
|
|
||||||
|
if(ret < 4) {
|
||||||
|
errno = EIO;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data[0] != 0) {
|
||||||
|
errno = EFAULT;
|
||||||
|
|
||||||
|
*fail = data[0];
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ uint32_t ingenic_sdram_size(void *hndl);
|
|||||||
int ingenic_rebuild(void *hndl);
|
int ingenic_rebuild(void *hndl);
|
||||||
int ingenic_loadstage(void *hndl, int id, const char *filename);
|
int ingenic_loadstage(void *hndl, int id, const char *filename);
|
||||||
int ingenic_stage1_debugop(void *device, const char *filename, uint32_t op, uint32_t pin, uint32_t base, uint32_t size);
|
int ingenic_stage1_debugop(void *device, const char *filename, uint32_t op, uint32_t pin, uint32_t base, uint32_t size);
|
||||||
|
int ingenic_memtest(void *hndl, const char *filename, uint32_t base, uint32_t size, uint32_t *fail);
|
||||||
|
|
||||||
#define CMDSET_SPL 1
|
#define CMDSET_SPL 1
|
||||||
#define CMDSET_USBBOOT 2
|
#define CMDSET_USBBOOT 2
|
||||||
|
36
spl_cmdset.c
36
spl_cmdset.c
@ -20,6 +20,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -54,9 +55,42 @@ static int spl_stage1_op(uint32_t op, uint32_t pin, uint32_t base, uint32_t size
|
|||||||
static int spl_memtest(int argc, char *argv[]) {
|
static int spl_memtest(int argc, char *argv[]) {
|
||||||
if(argc != 1 && argc != 3) {
|
if(argc != 1 && argc != 3) {
|
||||||
printf("Usage: %s [BASE <SIZE>]\n", argv[0]);
|
printf("Usage: %s [BASE <SIZE>]\n", argv[0]);
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return spl_stage1_op(STAGE1_DEBUG_BOOT, 0, 0, 0); // TODO
|
uint32_t start, size;
|
||||||
|
|
||||||
|
if(argc == 3) {
|
||||||
|
start = strtoul(argv[1], NULL, 0);
|
||||||
|
size = strtoul(argv[2], NULL, 0);
|
||||||
|
} else {
|
||||||
|
start = SDRAM_BASE;
|
||||||
|
size = ingenic_sdram_size(shell_device());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cfg_getenv("STAGE1_FILE") == NULL) {
|
||||||
|
printf("Variable STAGE1_FILE is not set\n");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fail;
|
||||||
|
|
||||||
|
int ret = ingenic_memtest(shell_device(), cfg_getenv("STAGE1_FILE"), start, size, &fail);
|
||||||
|
|
||||||
|
if(ret == -1) {
|
||||||
|
if(errno == EFAULT) {
|
||||||
|
printf("Memory test failed at address 0x%08X\n", fail);
|
||||||
|
} else {
|
||||||
|
perror("ingenic_memtest");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Memory test passed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spl_gpio(int argc, char *argv[]) {
|
static int spl_gpio(int argc, char *argv[]) {
|
||||||
|
13
usbdev.c
13
usbdev.c
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* JzBoot: an USB bootloader for JZ series of Ingenic(R) microprocessors.
|
* JzBoot: an USB bootloader for JZ series of Ingenic(R) microprocessors.
|
||||||
* Copyright (C) 2010 Sergey Gridassov <grindars@gmail.com>
|
* Copyright (C) 2010 Sergey Gridassov <grindars@gmail.com>,
|
||||||
|
* Peter Zotov <whitequark@whitequark.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -143,6 +144,16 @@ int usbdev_sendbulk(void *hndl, void *data, int size) {
|
|||||||
return translate_libusb(libusb_bulk_transfer(hndl, ENDPOINT_OUT, data, size, &trans, CONTROL_TIMEOUT));
|
return translate_libusb(libusb_bulk_transfer(hndl, ENDPOINT_OUT, data, size, &trans, CONTROL_TIMEOUT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int usbdev_recvbulk(void *hndl, void *data, int size) {
|
||||||
|
int trans;
|
||||||
|
|
||||||
|
debug(LEVEL_DEBUG, "Bulk: reading data %p, size %d\n", data, size);
|
||||||
|
|
||||||
|
int ret = translate_libusb(libusb_bulk_transfer(hndl, ENDPOINT_IN, data, size, &trans, CONTROL_TIMEOUT));
|
||||||
|
|
||||||
|
return ret == -1 ? -1 : trans;
|
||||||
|
}
|
||||||
|
|
||||||
static int translate_libusb(int code) {
|
static int translate_libusb(int code) {
|
||||||
switch(code) {
|
switch(code) {
|
||||||
case LIBUSB_SUCCESS:
|
case LIBUSB_SUCCESS:
|
||||||
|
4
usbdev.h
4
usbdev.h
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* JzBoot: an USB bootloader for JZ series of Ingenic(R) microprocessors.
|
* JzBoot: an USB bootloader for JZ series of Ingenic(R) microprocessors.
|
||||||
* Copyright (C) 2010 Sergey Gridassov <grindars@gmail.com>
|
* Copyright (C) 2010 Sergey Gridassov <grindars@gmail.com>,
|
||||||
|
* Peter Zotov <whitequark@whitequark.org>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -32,5 +33,6 @@ void *usbdev_open(void *dev);
|
|||||||
void usbdev_close(void *hndl);
|
void usbdev_close(void *hndl);
|
||||||
int usbdev_vendor(void *hndl, int direction, uint8_t req, uint16_t value, uint16_t index, void *data, uint16_t size);
|
int usbdev_vendor(void *hndl, int direction, uint8_t req, uint16_t value, uint16_t index, void *data, uint16_t size);
|
||||||
int usbdev_sendbulk(void *hndl, void *data, int size);
|
int usbdev_sendbulk(void *hndl, void *data, int size);
|
||||||
|
int usbdev_recvbulk(void *hndl, void *data, int size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user