How to write to any address with any data? - origen-sdk

A lot of the Origen protocol plugins offer only top level register read and write methods, which requires one of the input arguments to be a register object. If i want to just write to a location that's neither a defined register or memory location, i.e. i just want to do a write to an address with a data, how do I do that please?

If you just want to write data and are not bothered about tracking the value or needing to do bit-level read/store operations, then all Origen read/write_register methods should accept a value in place of a register object, as long as you supply the address:
dut.write_register 0x1234_5678, address: 0x4000_0010
A better approach however, is via the read/write memory API, this is equivalent to the above:
dut.mem(0x4000_0010).write!(0x1234_5678)
When you call that API it will generate an anonymous register object in the background to keep track of the value and to provide bit-level access. In other words, you get the same capabilities as if you had defined a register at that location.
For example, if you need to check what you have written there:
dut.mem(0x4000_0010).data # => 0x1234_5678
You can read/store at bit-level, and also sync if you are using an OrigenLink or OrigenSim compliant debug environment:
dut.mem(0x4000_0010)[15..0].read!(0x5678)
dut.mem(0x4000_0010)[31..16].store!
dut.mem(0x4000_0010).sync
Memory can also be accessed via a sub-block with a local address, however there is only one memory object and this will return the same register object as for the corresponding global address. For example, say in this case that we have been writing to an IP block that has a base_address of 0x4000_0000 within the DUT.
Within the Origen pattern source code for that block, you can use relative addressing:
# From within the IP-level model/controller
mem(0x10).write!(0x1234_5678)
# Accessing the same location via a global path
dut.mem(0x4000_0010).data # => 0x1234_5678
By default, mem returns 32-bit register objects and the address must be aligned. The width can be changed on a per-DUT basis:
dut.memory_width = 16
dut.mem(0x4000_0010).size # => 16
Finally, the sync method will accept a size argument which corresponds to the number of memory locations to read out:
(byebug) dut.mem(0x4000_0000).sync(10)
40000000: FFFE0080
40000004: 00005555
40000008: 00000000
4000000C: 00000000
40000010: 12345678
40000014: 00000000
40000018: FFFFFFFF
4000001C: FFFFFFFF
40000020: FFFFFFFF
40000024: FFFFFFFF

Related

Cheating with the gp register on RISC-V - what could go wrong?

I absolutely have to pass an initialisation value to a dynamic library/module (everything is written in assembly) for some RISC-V code. The only way I seem to be able to do this is to use the gp register - and the code I am using runs and there are no crashes (yet). It is used to pass the value of a stack where a couple of initialisation values are stored.
70 PUSH gp
71 mv gp, s10
72 call dlopen
73 POP gp
(PUSH and POP are my main stack macros, s10 points to the stack I am using to store values for initialisation).Everything runs on top of GNU libc/libdl.
I restore the value of gp as quickly as I can: everything says never change the value of this register - so what could go wrong, or if it works, can I just relax about it?
The answer was to write some library code that would allow access to read and write a memory location that held the value. So the writer (main executable) could write to the address and then the reader (library needing the address) reads it as required.

MODBUS protocol coils order

MODBUS is positioned as a universal data transferring protocol which works in almost every media.
When working with industrial devices they are usually using several slots to maintain different types of I/O modules.
I've read in modbus.org docs that the enumeration of coils (Digital Outputs) is starting from 0 position.
In the PDU Coils are addressed starting at zero. Therefore coils
numbered 1-16 are addressed as 0-15
Currently the slots are used in this way. Module 5056D (DO module) is connected as second.
Would the accessing address to the first Digital Output change from 00 to another if the module is swapped with neighbor modules or it would change only if to insert another DO module in the first slot?
Then I guess it would be 16+1=17; 17-1=16 accessing address=16?

Buffer overflow exploitation 101

I've heard in a lot of places that buffer overflows, illegal indexing in C like languages may compromise the security of a system. But in my experience all it does is crash the program I'm running. Can anyone explain how buffer overflows could cause security problems? An example would be nice.
I'm looking for a conceptual explanation of how something like this could work. I don't have any experience with ethical hacking.
First, buffer overflow (BOF) are only one of the method of gaining code execution. When they occur, the impact is that the attacker basically gain control of the process. This mean that the attacker will be able to trigger the process in executing any code with the current process privileges (depending if the process is running with a high or low privileged user on the system will respectively increase or reduce the impact of exploiting a BOF on that application). This is why it is always strongly recommended to run applications with the least needed privileges.
Basically, to understand how BOF works, you have to understand how the code you have build gets compiled into machine code (ASM) and how data managed by your software is stored in memory.
I will try to give you a basic example of a subcategory of BOF called Stack based buffer overflows :
Imagine you have an application asking the user to provide a username.
This data will be read from user input and then stored in a variable called USERNAME. This variable length has been allocated as a 20 byte array of chars.
For this scenario to work, we will consider the program's do not check for the user input length.
At some point, during the data processing, the user input is copied to the USERNAME variable (20bytes) but since the user input is longer (let's say 500 bytes) data around this variable will be overwritten in memory :
Imagine such memory layout :
size in bytes 20 4 4 4
data [USERNAME][variable2][variable3][RETURN ADDRESS]
If you define the 3 local variables USERNAME, variable2 and variable3 the may be store in memory the way it is shown above.
Notice the RETURN ADDRESS, this 4 byte memory region will store the address of the function that has called your current function (thanks to this, when you call a function in your program and readh the end of that function, the program flow naturally go back to the next instruction just after the initial call to that function.
If your attacker provide a username with 24 x 'A' char, the memory layout would become something like this :
size in bytes 20 4 4 4
data [USERNAME][variable2][variable3][RETURN ADDRESS]
new data [AAA...AA][ AAAA ][variable3][RETURN ADDRESS]
Now, if an attacker send 50 * the 'A' char as a USERNAME, the memory layout would looks like this :
size in bytes 20 4 4 4
data [USERNAME][variable2][variable3][RETURN ADDRESS]
new data [AAA...AA][ AAAA ][ AAAA ][[ AAAA ][OTHER AAA...]
In this situation, at the end of the execution of the function, the program would crash because it will try to reach the address an invalid address 0x41414141 (char 'A' = 0x41) because the overwritten RETURN ADDRESS doesn't match a correct code address.
If you replace the multiple 'A' with well thought bytes, you may be able to :
overwrite RETURN ADDRESS to an interesting location.
place "executable code" in the first 20 + 4 + 4 bytes
You could for instance set RETURN ADDRESS to the address of the first byte of the USERNAME variable (this method is mostly no usable anymore thanks to many protections that have been added both to OS and to compiled programs).
I know it is quite complex to understand at first, and this explanation is a very basic one. If you want more detail please just ask.
I suggest you to have a look at great tutorials like this one which are quite advanced but more realistic

mpc85xx(P2040) startup using Nor Flash, where is Nor Flash mapped to?

I'm porting u-boot to P2040 based board these days.
As u-boot/arch/powerpc/mpc85xx/start.s commented:
The processor starts at 0xffff_fffc and the code is first executed in the last 4K page in flash/rom.
In u-boot/arch/powerpc/mpc85xx/resetvec.S:
.section .resetvec,"ax"
b _start_e500
And in u-boot.lds linker script:
.resetvec RESET_VECTOR_ADDRESS :
{
KEEP(*(.resetvec))
} :text = 0xffff
The reset vector is at 0xffff_fffc, which contains a jump instruction to _start_e500.
The E500MCRM Chapter 6.6 mentioned:
This default TLB entry translates the first instruction fetch out of reset(at effective address 0xffff_fffc).
This instruction should be a branch to the beginning of this page.
So, if I configure the HCW to let powerpc boot from Nor Flash, why should I suppose that the Nor Flash's
last 4K is mapped to 0xffff_f000~0xffff_ffff? Since there're no LAW setup yet and the default BR0/OR0 of Local Bus
does not match that range. I’m confused about how Nor Flash be access at the very beginning of core startup.
Another question is:
Does P2040 always have MMU enabled so as to translate effective address to real address even at u-boot stage?
If so, beside accessing to CCSRBAR, all other memory access should have TLB entry setup first.
Best Regards,
Hook Guo

AHCI specification

I have a question regarding the AHCI spec:
Is the variable pDmaXferCnt in the port used when the transfer is a DMA write or read?
The description in the spec seems to indicate that it isn't, but the PRDs are used instead.
But how does the HBA know how much data is to be sent or received to/from a SATA device?
This information will be available in the sector count of a H2D FIS, but unless I have overlooked it there doesn't seem to be a register of variable that holds this value.
The DX:transmit state also seems to indicate that pDmaXferCnt will have a set value, yet I can’t see where it would be set for a DMA read/write operation.
Thanks
From the spec:
"Implementation Note:
HBA state variables are used to describe the required externally visible behavior. Implementations are not required to have internal state values that directly correspond to these variables." - meaning you (maybe) won't find the pDmaXferCnt externally in a register.
There is another way to track the count though.
Under the HBA Memory Space Usage part of the AHCI spec, there are the data structures of the command list (list of command headers) and the command table (pointed to by the command header, each command table is a command to be sent). These are both accessible to the HBA.
In the command header in DW0 is the PRDTL - which is the count of how many PRD's to be used in the transfer.
Now in the actual command table that the command header points to, contains the actual PRD's, in each PRD is their own DBC or data byte count (amount of data in bytes to be DMA'd at the location specified in DBA). So if you take the each of the PRD's * there own DBC's and add them up you'll get the amount of data to be transfered.
Alternately in the in the command header DW1 is the PRDBC which is the count of bytes transfered, so you could check that after the command.
HBA - Host Bus Adapter
PRDTL - Physical Region Descriptor Table Length
PRD - Physical Region Descriptor (tracks where in physical memory and the count of bytes is to be transfered)
DBC - data byte count (inside a PRD)
DBA - data base address (physical address inside a PRD)
PRDBC - Physical Region Descriptor Byte Count
DMA - direct memory access
For more reading: http://www.intel.com/content/www/us/en/io/serial-ata/serial-ata-ahci-spec-rev1-3-1.html

Resources