In the Base + Offset addressing, Offset address is also known as:
(a) Physical Address
(b) Logical Address
(c) Actual Address
(d) Instruction Address
(e) None of these
Kindly answer it. To me it might be (b) or (d).
Am I right?
Offset address is also known as relative address.
so the right answer is (e)
In this context an offset is sometimes called a relative address. In IBM System/360 instructions, a 12-bit offset embedded within certain instructions provided a range of between 0 and 4096 bytes.
(d) Instruction Address
Base + Offset addressing, Offset address is also known as Instruction Address.
Related
I found a strange mismatch in the reference manual for the OTP memory size:
Accordingly to the manual (RM0385, page 78) the start-address of the OTP memory begins at 0x1FF0 F000 and ends at address: 0x1FF0 F41F (in AXIM mode) and is declared as a memory area with the size of 1024 bytes:
But if I calculate 0x1FF0F41F - 0x1FF0F000 + 1 I get a total of 1056 bytes OTP memory?!
Same addresses are set in the latest CMSIS header V1.17.0 (https://raw.githubusercontent.com/STMicroelectronics/STM32CubeF7/master/Drivers/CMSIS/Device/ST/STM32F7xx/Include/stm32f746xx.h):
#define FLASH_OTP_BASE 0x1FF0F000UL
#define FLASH_OTP_END 0x1FF0F41FUL
Is this a typo in the manual or is my calculation wrong?
I don't think it's a typo, and your calculation is correct.
My explanation is as follows:
Chapter 3.6 of the same Reference Manual shows the organization of the one-time programmable (OTP) part of the OTP area, and explains:
The OTP area is divided into 16 OTP data blocks of 64 bytes and one lock OTP block of 16 bytes. The OTP data and lock blocks cannot be erased. The lock block contains 16 bytes LOCKBi (0 ≤ i ≤ 15) to lock the corresponding OTP data block (blocks 0 to 15). (...)
So it consists of 1024 data bytes and 16 lock bytes. I guess the lock bytes are implemented as special "registers" and are not considered part of the sector. It's more a matter of definition and does not really matter that much.
There probably is a 1024-byte sector to write the (one-time programmable) data to, but the address range is slightly larger because the lock bits have to be addressed as well.
Using a PCAN VIEW, I determined the "rudder position" address (Yamaha Outboard), to be 166792448, and using CAN_Rx_MessageProc_ST_0 got the outboard position from bytes 4 and 5 of the 8 byte array:
RUDDER_ANGLE_RAW := WORD_TO_INT((256*MESSAGE_RX_NMEA[5]) + MESSAGE_RX_NMEA[4]);
I assumed that this Address would stay constant, but when the outboard changed, the address also changed - new address was 166792453. And further to this, after a power cycle, the address changed again to 166792456.
Assuming this has to do with address claiming, conflict, and the address changing.
The questions I have (and I have tried to grasp concepts but as a newby here am struggling) are thus:
1 Is there a range within in which this address will stay?
2 Can I get information out of the 8 byte received data (such as "yamaha outboard" or manufacturer specific info) that I could use to determine what the actual address is?
IF there is a range, I could write a procedure to scan the range, looking for the manufacturer ID, and thus determine the correct address.
Any help appreciated would be appreciated!
This question refers to an architecture using segmentation with paging. In this architecture, the 32-bit virtual address is divided into fields as follows:
4 bit segment number | 12 bit page number |
16 bit offset
Find the physical address corresponding to each of the following virtual addresses (answer "bad virtual address" if the virtual address is invalid).
1.00000000
2.20022002
3.10015555
Please help me with this, i dont know how to create page table and segment table for this mapping !!!
You are a little shy on details, so lets fill in a few:
Each segment has a 4096 (=2^12) entry translation table associated with it; otherwise it would not be interesting.
Each entry will contain a physical base address.
The extra offset will be added to this base address to find the final one.
So, in this hypothetical MMU, we could have a function like:
paddr_t translate(uint32_t vaddr) {
return segment[vaddr>>28].page[(vaddr>>16)&0xfff] + (vaddr & 0xffff);
}
A real (useful) mmu would have a bit more like:
paddr_t translate(uint32_t vaddr) {
seg_t *seg;
page_t *page;
if ((seg = segment[vaddr>>28]) && (page = seg->pagetab[(vaddr>>16)&0xfff])) {
return page->base + (vaddr & 0xffff);
} else {
raise(SEGV);
}
}
this is showing the sparseness of both segments and page mappings. It would likely have some permissions, as well, but this should help get you to the next obstacle.
Hi I'm writing a kernel and plan to use MSI interrupt for PCI devices.
However, I'm also quite confused by the documentations.
My understanding about MSI are as follow:
From PCI device point of view:
Documentations indicate that I
need to find Capabillty ID = 0x05 to locate 3 registers: Message control (MCR), Message Address (MAR) and Message Data (MDR) registers
MCR provide control functionality for MSI interrupt,
MAR provide the physical address the PCI device
will write once interrupt occurs
MDR forms out the actual data it will write into the physical address
From CPU point of view:
Documentation shows that Message Address register contains fixed top of 0xFEE, and following by destination ID (LAPIC ID) and other controlling bits as follow:
The Message Data register will contain the following information, including the interrupt vector:
After reading all of these, I am thinking if the APIC_ID is 0x0h would the Message Address conflict with the Local APIC memory mapping? Although the address of FEE00000~FEE00010 are reserved.
In addition, is it true that the vector number in MDR is corresponding to the IDT vector number. In other words, if I put MAR = 0xFEE0000C (Destination ID = 0, Using logical APIC ID) and MDR = 0x0032 (edge trigger, Vector = 50) and enable the MSI interrupt, then once the device issues an interrupt CPU would correspondingly run the function pointed by IDT[50]? After that I write 0h to EOI register to end it?
Finally, according to the documentation, the upper 32 bit of MAR is not used? Can anyone help on this?
Thanks a lot!
Your understanding of how to detect and program MSI in a PCI (or PCIe) device is correct.*
The message address controls the destination (which CPU the interrupt is sent to), while the message data contains the vector number. For normal interrupts, all bits of the message data should be 0 except for the low 8 bits, which contain the vector.
The vector is an index into the IDT, so if the message data is 0x0032, the interrupt is delivered through entry 50 of the IDT.**
If the Destination ID in an interrupt message is 0, the Message Address of the MSI does match the default address of the local APIC, but they do not conflict, because the APIC can only be written by the CPU and MSIs can only be written by devices.
On x86 platforms, the upper 32 bits of the message address must be 0. This can be done by setting the upper part of the message address to 0 or by programming the device to use a 32-bit message address (in which case the upper message address register is not used). The PCI spec was designed to work with systems where 64-bit MSI addresses are used, but x86 systems never use the upper 32 bits of the message address.
Reprogramming the APIC base address by writing to the APIC_BASE MSR does not affect the address range used for MSI; it is always 0xFEExxxxx.
* You should also look at the MSI-X capability, because some devices support MSI-X but not MSI. MSI-X is a bit more flexible, which inevitably makes it a bit more complicated.
** When using the MSI capability, the message data isn't exactly the value in the Message Data Register (MDR). The MSI capability allows the device to use several contiguous vectors. When the device sends an interrupt message, it replaces the low bits of the MDR with a different value depending on the interrupt cause within the device.
I'm struggling to understand where to get the address of a device on a device tree? As an example how do I know that I should set <0x00900000 0x20000> in here.
Is memory mapped IO done in the hardware (the processor itself) or in software and do I just have to pass the right address in the device tree?
Is the address hardcoded on the processor or can I just set an arbitrary address? I cannot find anything in my reference manual about setting a certain address in the device tree
These kind of addresses can be found in the Reference Manual of the processor.
You can find the link here.
Take a look at the chapter 48 (OCRAM On-chip RAM Memory Controller) and more specifically at the section 48.2.1 (page 4118):
The total on-chip RAM size for the chip is 128 Kbytes, organized as 16K x 64 bits,mapped from 0x00900000 to 0x0091FFFF
This is where come from the values <0x00900000 0x20000> from the dtsi file, corresponding to the base address and the offset.
These values are in dts/dtsi file provided by the chip maker.