Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions boards/rapidsilicon/virgo_proto/virgo_proto.dts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
chosen {
zephyr,console = &uart0;
zephyr,shell-uart = &uart0;
zephyr,sram = &sram;
zephyr,sram = &dlm;
zephyr,flash = &ilm;
};
};
Expand All @@ -37,6 +37,24 @@
};

&cpu0 {
clock-frequency = <26666667>;
clock-frequency = <26666667>;
};

&spi0 {
status = "okay";
clock-frequency = <26666667>;
m25p32: qspi-nor-flash@0 {
compatible = "jedec,spi-nor";
size = <16777216>;
spi-max-frequency = <13333333>;
jedec-id = [20 20 16]; // ID of flash on soc protoype
status = "okay";
reg = <0>;
sfdp-bfp = [
e5 D8 f1 ff ff ff ff 00 44 eb 08 6b 08 3b 04 bb
fe ff ff ff ff ff 00 ff ff ff 44 eb 0c D8 0f 52
10 d8 00 ff
];
};
};

14 changes: 14 additions & 0 deletions dts/bindings/sram/rapidsi,ocm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright (c) 2014, Rapid Silicon
# SPDX-License-Identifier: Apache-2.0

description: Generic on-chip Memory

compatible: "rapidsi,ocm"

include: base.yaml

bus: simple_bus

properties:
reg:
required: false
39 changes: 20 additions & 19 deletions dts/riscv/rapidsilicon/rapidsi_virgo.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,26 @@
0xE2001000 0x1000>;
};

sram: memory@A0300000 {
compatible = "rapidsi,dlm";
device_type = "memory";
reg = <0xA0300000 DT_SIZE_K(32)>;
status = "okay";
};

ilm: ilm@A0200060 {
compatible = "rapidsi,ilm";
device_type = "memory";
reg = <0xA0200060 (DT_SIZE_K(64)-0x00000060)>;
status = "okay";
};
memory: memory {
compatible = "rapidsi,ocm";
#address-cells = <1>;
#size-cells = <1>;
ranges;

dlm: memory@A0300000 {
compatible = "rapidsi,dlm";
device_type = "memory";
reg = <0xA0300000 DT_SIZE_K(32)>;
status = "okay";
};

ilm: memory@A0200060 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ilm: memory@A0200060 {
ilm: memory@A0200060 {

Should the address be A0200060 or A0200000?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can definitely change it. Our FSBL binary is run from 0xA020005C because the first 5C bytes are taken by UBI header. The Zephyr binary address is kept 0xA0200060 due to alignment issues and also considering UBI header space.

If we know how Zephyr will be put in ILM, we can then think of its execution location accordingly.

Copy link
Collaborator

@rahul-r-shah rahul-r-shah Jul 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can definitely change it. Our FSBL binary is run from 0xA020005C because the first 5C bytes are taken by UBI header. The Zephyr binary address is kept 0xA0200060 due to alignment issues and also considering UBI header space.

If we know how Zephyr will be put in ILM, we can then think of its execution location accordingly.

Ok, I understand you are suggesting that the binary will consist of the UBI header and the actual Zephyr binary too and we will be loading the entire binary into the ILM. But what about the BOP header of the zephyr binary.

Zephyr should be loaded the same way as FSBL. So the ways of loading are

  1. Via openOCD (JTAG): Do we currently load the entire binary (UBI binary with BOP or only the zephyr binary?) and then jump to the FSBL (in this case zephyr)? In this case the loading happens via bootrom code and the FSBL (zephyr image will have to have code for FSBL in the BOP) will be loaded into the ILM (I believe the UBI and the BOP will be stripped and all the security operations, like authentication and decryption will be performed )
  2. Via UART: In this case the CLI will be in XMODEM command and in this mode the unsecure binary will be downloaded
  3. From Flash: In this case the bootrom will decrypt and authenticate (if secure) binary and then will load the FSBL (zephyr) in the load address

Copy link
Collaborator Author

@junaidaslamRS junaidaslamRS Jul 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment, we are loading Zephyr using xmodem command on CLI over USART.

For loading Zephyr via Flash, we will have to use the same method which we use for FSBL on FLASH. Using OpenOCD we load everything on the flash. Then we reboot into SPI boot mode and bootrom then loads Zephyr, after security stuff, into the ILM. In this case, we will need a UBI header of the BOP which will have Zephyr as its binary.

compatible = "rapidsi,ilm";
device_type = "memory";
reg = <0xA0200060 (DT_SIZE_K(64)-0x00000060)>;
status = "okay";
};
};

soc {
compatible = "rapidsi,virgo";
Expand Down Expand Up @@ -98,12 +105,6 @@
};
};
};

flash: flash@B0000000 {
compatible = "micron,m25p32";
reg = <0xB0000000 DT_SIZE_M(16)>;
status = "disabled";
};

uart0: serial@a0420020 {
compatible = "ns16550";
Expand Down
127 changes: 107 additions & 20 deletions samples/hello_world/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,134 @@
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/flash.h>
#include <scu.h>

#define ATTR_INF "\x1b[32;1m" // ANSI_COLOR_GREEN
#define ATTR_ERR "\x1b[31;1m" // ANSI_COLOR_RED
#define ATTR_RST "\x1b[37;1m" // ANSI_COLOR_RESET

#define FLASH_RW_SIZE 255

void Flash_Test(const struct device *flash, uint32_t FLASH_ADDR, uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) {
int errorcode = 0;
uint8_t flash_data_write[FLASH_RW_SIZE] = {0};
uint8_t flash_data_read[FLASH_RW_SIZE] = {0};
errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE);
if(errorcode < 0) {
printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode,ATTR_RST);
}
else {
printf("%s Reading Back Before Erasing Flash%s\n", ATTR_INF,ATTR_RST);
for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) {
printf("%s %d%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":"");
} printf("\n");
}
errorcode = flash_erase(flash, FLASH_ADDR, 0x1000);
if(errorcode < 0) {
printf("%s\nError Erasing the flash at 0x%08x offset errorcode:%d%s\n", ATTR_ERR, FLASH_ADDR, errorcode,ATTR_RST);
} else {
printf("%s\nSuccessfully Erased Flash\n", ATTR_RST);
errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE);
if(errorcode < 0) {
printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode,ATTR_RST);
} else {
printf("%s Reading Back After Erasing Area of Flash%s\n", ATTR_INF,ATTR_RST);
for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) {
if(flash_data_read[i] != 0xff) {
errorcode = -1;
}
}
}
if(errorcode == -1) {
printf("%s\nFlash erase at 0x%08x did not produce correct results%s\n", ATTR_ERR, FLASH_ADDR,ATTR_RST);
for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) {
printf("%s 0x%02x%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":"");
} printf("\n");
} else {
printf("%s\nSuccessfully performed erase to flash with code:%d%s\n", ATTR_INF, errorcode,ATTR_RST);
}
errorcode = 0;
}

if(errorcode == 0) {
printf("%s Writing the following data After Erasing Flash%s\n", ATTR_INF,ATTR_RST);
for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) {
flash_data_write[i] = (rand() % (FLASH_RW_SIZE - 1 + 1)) + 1;
printf("%s %d%s", ATTR_INF, flash_data_write[i],i%FORMATTER==0?"\n":"");
} printf("\n");
errorcode = flash_write(flash, FLASH_ADDR, flash_data_write, FLASH_RW_SIZE);
}

if(errorcode < 0) {
printf("%s \nError writing to flash with code:%d%s\n", ATTR_ERR, errorcode,ATTR_RST);
} else {
printf("%s \nSuccessfully written to flash with code:%d Resetting the reading buffer....%s\n", ATTR_INF, errorcode,ATTR_RST);
memset(flash_data_read, 0, FLASH_RW_SIZE);
errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE);
if(errorcode < 0) {
printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode,ATTR_RST);
} else {
printf("%s Successfully Read from flash with code:%d%s\n", ATTR_INF, errorcode,ATTR_RST);
bool Data_Validated = true; uint8_t Mismatch_count = 0;
for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) {
if(flash_data_read[i] != flash_data_write[i]) {
Data_Validated = false; Mismatch_count++;
printf("%s %d - Read:%d != Write:%d%s\n", ATTR_ERR, i, flash_data_read[i], flash_data_write[i],ATTR_RST);
}
}
if(!Data_Validated) {
printf("%s Flash Integrity Check Failed With %d Mismatched Entries%s\n", ATTR_ERR,Mismatch_count,ATTR_RST);
} else{
printf("%s Flash Integrity Check Passed!!!%s\n", ATTR_INF,ATTR_RST);
}
}
}
}

int main(void)
{
int Cnt = 0;
struct sensor_value lvTemp = {0}, lvVolt = {0};
uint8_t chip_id = 0, vendor_id = 0, errorcode = 0;
uint8_t chip_id = 0, vendor_id = 0;
int errorcode = 0;

soc_get_id(&chip_id, &vendor_id);
const struct device *pvt = DEVICE_DT_GET(DT_NODELABEL(pvt0));

if(pvt == NULL) {
printf("pvt has status disabled or driver is not initialized...\n");
} else {
printf("pvt Object is Created\n");
}
soc_get_id(&chip_id, &vendor_id);

if(!device_is_ready(pvt)) {
printf("Error with device initialization\n");
return -ENODEV;
const struct device *pvt = DEVICE_DT_GET(DT_NODELABEL(pvt0));
const struct device *flash = DEVICE_DT_GET(DT_NODELABEL(m25p32));

if((pvt == NULL) || (!device_is_ready(pvt))) {
printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST);
} else {
errorcode = sensor_channel_get(pvt, SENSOR_CHAN_DIE_TEMP, &lvTemp);
if(errorcode) {
printf("Error fetching temperature value. Error code:%u\n", errorcode);
printf("%s pvt Object is Created %s\n", ATTR_INF, ATTR_RST);
errorcode = sensor_channel_get(pvt, SENSOR_CHAN_DIE_TEMP, &lvTemp);
if(errorcode == 0) {
printf("%s Error fetching temperature value. Error code:%u%s\n", ATTR_ERR, errorcode,ATTR_RST);
}

errorcode = sensor_channel_get(pvt, SENSOR_CHAN_VOLTAGE, &lvVolt);
if(errorcode) {
printf("Error fetching Voltage value. Error code:%u\n", errorcode);
if(errorcode == 0) {
printf("%s Error fetching Voltage value. Error code:%u%s\n", ATTR_ERR, errorcode,ATTR_RST);
}

printf("Die Temperature:%d Voltage:%d\n", lvTemp.val1, lvVolt.val1);
printf("%s Die Temperature:%d Voltage:%d%s\n", ATTR_INF, lvTemp.val1, lvVolt.val1,ATTR_RST);
}

if((flash == NULL) || (!device_is_ready(flash))) {
printf("%s flash has status disabled or driver is not initialized...%s\n", ATTR_ERR,ATTR_RST);
} else {
printf("%s flash Object is Created\n", ATTR_INF);
Flash_Test(flash, 0x1000, 0, 20);
}

while(true) {
printf(
"%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Die[Temp:%d Volt:%d] mTimerClock = %d Hz\r",
Cnt++,
"%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Die[Temp:%d Volt:%d] mTimerClock = %d Hz\r",
ATTR_RST, Cnt++,
CONFIG_BOARD_TARGET,
chip_id, vendor_id, lvTemp.val1, lvVolt.val1,
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
Expand Down