Commit f0fdbe5b authored by salcaide's avatar salcaide
Browse files

Fixed bug in crossbar configuration

parent 86907eee
...@@ -71,32 +71,30 @@ unsigned pmu_configure_crossbar(unsigned int output, unsigned int event_index) { ...@@ -71,32 +71,30 @@ unsigned pmu_configure_crossbar(unsigned int output, unsigned int event_index) {
#endif #endif
return (1); return (1);
} }
unsigned int ev_idx = event_index;
unsigned int ev_idx = (event_index & CROSSBAR_INPUTS ); //?
unsigned int fieldw = log2(CROSSBAR_INPUTS); unsigned int fieldw = log2(CROSSBAR_INPUTS);
//Blank Mask. It will reset any configuration field //Blank Mask. It will reset any configuration field
unsigned int bmask ; unsigned int bmask ;
bmask=(1<<fieldw)-1; bmask=(1<<fieldw)-1;
unsigned int tmp,reg_idx,field_idx;
//Get the bit position if all registers where concatenated //Get the bit position if all registers where concatenated
unsigned tmp,reg_idx,field_idx; tmp = output*fieldw;
tmp = event_index*fieldw;
//Get the register index given a register width //Get the register index given a register width
reg_idx = tmp/REG_WIDTH; reg_idx = tmp/REG_WIDTH;
//Get the position of the crossbar configuration field //Get the position of the crossbar configuration field
field_idx = (int)tmp % REG_WIDTH; field_idx = (int)tmp % REG_WIDTH;
// check if the configuration field has bits in two different registers // check if the configuration field has bits in two different registers
unsigned fieldw1 = fieldw; // Bits in first register unsigned int fieldw1 = fieldw; // Bits in first register
unsigned fieldw2 = 0; //Bits in second register unsigned int fieldw2 = 0; //Bits in second register
if ((field_idx+fieldw)>REG_WIDTH) { if ((field_idx+fieldw)>REG_WIDTH) {
fieldw1 = REG_WIDTH-field_idx; fieldw1 = REG_WIDTH-field_idx;
fieldw2 = fieldw - fieldw1; fieldw2 = fieldw - fieldw1;
// Clear previous field // Clear previous field
_PMU_CROSSBAR[reg_idx] &= (~((1<<fieldw1)-1) << field_idx); _PMU_CROSSBAR[reg_idx] &= (~(((1<<fieldw1)-1) << field_idx));
_PMU_CROSSBAR[reg_idx+1] &= ~((1<<fieldw2)-1); _PMU_CROSSBAR[reg_idx+1] &= ~((1<<fieldw2)-1);
//Set new values //Set new values
_PMU_CROSSBAR[reg_idx] |= ev_idx << field_idx; _PMU_CROSSBAR[reg_idx] |= ev_idx << field_idx;
_PMU_CROSSBAR[reg_idx] |= (ev_idx>>fieldw1); _PMU_CROSSBAR[reg_idx+1] |= (ev_idx>>fieldw1);
} else { } else {
_PMU_CROSSBAR[reg_idx] &= (~((bmask) << field_idx)); // Erease the output field _PMU_CROSSBAR[reg_idx] &= (~((bmask) << field_idx)); // Erease the output field
_PMU_CROSSBAR[reg_idx] |= ev_idx << field_idx; // Write into the output field _PMU_CROSSBAR[reg_idx] |= ev_idx << field_idx; // Write into the output field
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
// ======================== // ========================
//base addres for PMU on SoC //base addres for PMU on SoC
#define PMU_ADDR 0x80200000 #define PMU_ADDR 0x80100000
// ======================== // ========================
// General pourpose functions // General pourpose functions
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
// PMU base address // PMU base address
#define _PMUREG (_PMU_REG_TYPE(PMU_ADDR)) #define _PMUREG (_PMU_REG_TYPE(PMU_ADDR))
// PMU counter base address // PMU counter base address
#define _PMU_COUNTERS (_PMU_REG_TYPE(PMU_ADDR + R2A * BASE_CFG )) #define _PMU_COUNTERS (_PMU_REG_TYPE(PMU_ADDR + R2A * BASE_COUNTERS ))
// PMU crossbar base address // PMU crossbar base address
#define _PMU_CROSSBAR (_PMU_REG_TYPE(PMU_ADDR + R2A * BASE_CROSSBAR)) #define _PMU_CROSSBAR (_PMU_REG_TYPE(PMU_ADDR + R2A * BASE_CROSSBAR))
...@@ -82,6 +82,8 @@ ...@@ -82,6 +82,8 @@
#define CROSSBAR_REG1 (_PMU_CROSSBAR[1]) // Crossbar output register 1 #define CROSSBAR_REG1 (_PMU_CROSSBAR[1]) // Crossbar output register 1
#define CROSSBAR_REG2 (_PMU_CROSSBAR[2]) // Crossbar output register 2 #define CROSSBAR_REG2 (_PMU_CROSSBAR[2]) // Crossbar output register 2
#define CROSSBAR_REG3 (_PMU_CROSSBAR[3]) // Crossbar output register 3 #define CROSSBAR_REG3 (_PMU_CROSSBAR[3]) // Crossbar output register 3
#define CROSSBAR_REG4 (_PMU_CROSSBAR[4]) // Crossbar output register 4
#define CROSSBAR_REG5 (_PMU_CROSSBAR[5]) // Crossbar output register 5
// PMU overflow (I)nterrupt (E)nable register // PMU overflow (I)nterrupt (E)nable register
#define PMU_OVERLFOW_IE (_PMU_OVERFLOW[0]) #define PMU_OVERLFOW_IE (_PMU_OVERFLOW[0])
......
...@@ -71,32 +71,30 @@ unsigned pmu_configure_crossbar(unsigned int output, unsigned int event_index) { ...@@ -71,32 +71,30 @@ unsigned pmu_configure_crossbar(unsigned int output, unsigned int event_index) {
#endif #endif
return (1); return (1);
} }
unsigned int ev_idx = event_index;
unsigned int ev_idx = (event_index & CROSSBAR_INPUTS ); //?
unsigned int fieldw = log2(CROSSBAR_INPUTS); unsigned int fieldw = log2(CROSSBAR_INPUTS);
//Blank Mask. It will reset any configuration field //Blank Mask. It will reset any configuration field
unsigned int bmask ; unsigned int bmask ;
bmask=(1<<fieldw)-1; bmask=(1<<fieldw)-1;
unsigned int tmp,reg_idx,field_idx;
//Get the bit position if all registers where concatenated //Get the bit position if all registers where concatenated
unsigned tmp,reg_idx,field_idx; tmp = output*fieldw;
tmp = event_index*fieldw;
//Get the register index given a register width //Get the register index given a register width
reg_idx = tmp/REG_WIDTH; reg_idx = tmp/REG_WIDTH;
//Get the position of the crossbar configuration field //Get the position of the crossbar configuration field
field_idx = (int)tmp % REG_WIDTH; field_idx = (int)tmp % REG_WIDTH;
// check if the configuration field has bits in two different registers // check if the configuration field has bits in two different registers
unsigned fieldw1 = fieldw; // Bits in first register unsigned int fieldw1 = fieldw; // Bits in first register
unsigned fieldw2 = 0; //Bits in second register unsigned int fieldw2 = 0; //Bits in second register
if ((field_idx+fieldw)>REG_WIDTH) { if ((field_idx+fieldw)>REG_WIDTH) {
fieldw1 = REG_WIDTH-field_idx; fieldw1 = REG_WIDTH-field_idx;
fieldw2 = fieldw - fieldw1; fieldw2 = fieldw - fieldw1;
// Clear previous field // Clear previous field
_PMU_CROSSBAR[reg_idx] &= (~((1<<fieldw1)-1) << field_idx); _PMU_CROSSBAR[reg_idx] &= (~(((1<<fieldw1)-1) << field_idx));
_PMU_CROSSBAR[reg_idx+1] &= ~((1<<fieldw2)-1); _PMU_CROSSBAR[reg_idx+1] &= ~((1<<fieldw2)-1);
//Set new values //Set new values
_PMU_CROSSBAR[reg_idx] |= ev_idx << field_idx; _PMU_CROSSBAR[reg_idx] |= ev_idx << field_idx;
_PMU_CROSSBAR[reg_idx] |= (ev_idx>>fieldw1); _PMU_CROSSBAR[reg_idx+1] |= (ev_idx>>fieldw1);
} else { } else {
_PMU_CROSSBAR[reg_idx] &= (~((bmask) << field_idx)); // Erease the output field _PMU_CROSSBAR[reg_idx] &= (~((bmask) << field_idx)); // Erease the output field
_PMU_CROSSBAR[reg_idx] |= ev_idx << field_idx; // Write into the output field _PMU_CROSSBAR[reg_idx] |= ev_idx << field_idx; // Write into the output field
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
// ======================== // ========================
//base addres for PMU on SoC //base addres for PMU on SoC
#define PMU_ADDR 0x80200000 #define PMU_ADDR 0x80100000
// ======================== // ========================
// General pourpose functions // General pourpose functions
......
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
// PMU base address // PMU base address
#define _PMUREG (_PMU_REG_TYPE(PMU_ADDR)) #define _PMUREG (_PMU_REG_TYPE(PMU_ADDR))
// PMU counter base address // PMU counter base address
#define _PMU_COUNTERS (_PMU_REG_TYPE(PMU_ADDR + R2A * BASE_CFG )) #define _PMU_COUNTERS (_PMU_REG_TYPE(PMU_ADDR + R2A * BASE_COUNTERS ))
// PMU crossbar base address // PMU crossbar base address
#define _PMU_CROSSBAR (_PMU_REG_TYPE(PMU_ADDR + R2A * BASE_CROSSBAR)) #define _PMU_CROSSBAR (_PMU_REG_TYPE(PMU_ADDR + R2A * BASE_CROSSBAR))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment