bf8974ed | 21-Mar-2018 |
Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
ARC: Move cache global variables to arch_global_data
There is a problem with current implementation if we start U-Boot from ROM, as we use global variables before ther initialization, so these varia
ARC: Move cache global variables to arch_global_data
There is a problem with current implementation if we start U-Boot from ROM, as we use global variables before ther initialization, so these variables get overwritten when we copy .data section from ROM.
Instead we move these global variables into our "global data" structure so that we may really start from ROM.
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
show more ...
|
88ae27ed | 21-Mar-2018 |
Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
ARC: Move BCR encodings to separate header file
We're starting to use more and more BCRs and having their definitions in-lined in sources becomes a bit annoying so we move it all to a separate heade
ARC: Move BCR encodings to separate header file
We're starting to use more and more BCRs and having their definitions in-lined in sources becomes a bit annoying so we move it all to a separate header.
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
show more ...
|
c27814be | 21-Mar-2018 |
Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
ARC: Flush & invalidate D$ with a single command
We don't implement separate flush_dcache_all() intentionally as entire data cache invalidation is dangerous operation even if we flush data cache rig
ARC: Flush & invalidate D$ with a single command
We don't implement separate flush_dcache_all() intentionally as entire data cache invalidation is dangerous operation even if we flush data cache right before invalidation.
There is the real example: We may get stuck in the following code if we store any context (like BLINK register) on stack in invalidate_dcache_all() function.
BLINK register is the register where return address is automatically saved when we do function call with instructions like 'bl'.
void flush_dcache_all() { __dc_entire_op(OP_FLUSH); // Other code // }
void invalidate_dcache_all() { __dc_entire_op(OP_INV); // Other code // }
void foo(void) { flush_dcache_all(); invalidate_dcache_all(); }
Now let's see what really happens during that code execution:
foo() |->> call flush_dcache_all [return address is saved to BLINK register] [push BLINK] (save to stack) ![point 1] |->> call __dc_entire_op(OP_FLUSH) [return address is saved to BLINK register] [flush L1 D$] return [jump to BLINK] <<------ [other flush_dcache_all code] [pop BLINK] (get from stack) return [jump to BLINK] <<------ |->> call invalidate_dcache_all [return address is saved to BLINK register] [push BLINK] (save to stack) ![point 2] |->> call __dc_entire_op(OP_FLUSH) [return address is saved to BLINK register] [invalidate L1 D$] ![point 3] // Oops!!! // We lose return address from invalidate_dcache_all function: // we save it to stack and invalidate L1 D$ after that! return [jump to BLINK] <<------ [other invalidate_dcache_all code] [pop BLINK] (get from stack) // we don't have this data in L1 dcache as we invalidated it in [point 3] // so we get it from next memory level (for example DDR memory) // but in the memory we have value which we save in [point 1], which // is return address from flush_dcache_all function (instead of // address from current invalidate_dcache_all function which we // saved in [point 2] !) return [jump to BLINK] <<------ // As BLINK points to invalidate_dcache_all, we call it again and // loop forever.
Fortunately we may do flush and invalidation of D$ with a single one instruction which automatically mitigates a situation described above.
And because invalidate_dcache_all() isn't used in common U-Boot code we implement "flush and invalidate dcache all" instead.
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
show more ...
|
5e0c68ed | 21-Mar-2018 |
Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
ARC: Introduce is_isa_X() functions
Introduce is_isa_arcv2() and is_isa_arcompact() functions.
These functions only check configuration options and return compile-time constant so they can be used
ARC: Introduce is_isa_X() functions
Introduce is_isa_arcv2() and is_isa_arcompact() functions.
These functions only check configuration options and return compile-time constant so they can be used instead of #ifdef's to to write cleaner code.
Now we can write: -------------->8--------------- if (is_isa_arcv2()) ioc_configure(); -------------->8--------------- instead of: -------------->8--------------- ifdef CONFIG_ISA_ARCV2 ioc_configure(); endif -------------->8---------------
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
show more ...
|
e59c3797 | 28-Nov-2017 |
Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
ARC: add macro to get CPU id
ARCNUM [15:8] field in ARC_AUX_IDENTITY register allows us to uniquely identify each core in a multi-core system.
I.e. with help of this macro each core may get its ind
ARC: add macro to get CPU id
ARCNUM [15:8] field in ARC_AUX_IDENTITY register allows us to uniquely identify each core in a multi-core system.
I.e. with help of this macro each core may get its index in SMP system.
Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
show more ...
|