summary refs log tree commit diff stats
path: root/results/classifier/118/none/1122
diff options
context:
space:
mode:
Diffstat (limited to 'results/classifier/118/none/1122')
-rw-r--r--results/classifier/118/none/1122158
1 files changed, 158 insertions, 0 deletions
diff --git a/results/classifier/118/none/1122 b/results/classifier/118/none/1122
new file mode 100644
index 000000000..8c4f95dc6
--- /dev/null
+++ b/results/classifier/118/none/1122
@@ -0,0 +1,158 @@
+VMM: 0.275
+risc-v: 0.271
+virtual: 0.269
+mistranslation: 0.263
+semantic: 0.259
+peripherals: 0.259
+debug: 0.248
+graphic: 0.244
+vnc: 0.243
+permissions: 0.241
+ppc: 0.238
+TCG: 0.233
+hypervisor: 0.230
+PID: 0.230
+arm: 0.229
+architecture: 0.223
+device: 0.220
+KVM: 0.218
+kernel: 0.212
+assembly: 0.208
+register: 0.204
+user-level: 0.188
+performance: 0.177
+x86: 0.176
+i386: 0.171
+files: 0.166
+network: 0.164
+boot: 0.156
+socket: 0.120
+
+ARMv7M (Cortex M) NVIC does not make number of priority bits a board/SoC-configurable parameter
+Description of problem:
+In FreeRTOS code for function of `xPortStartScheduler()` in [`main/portable/GCC/ARM_CM4F/port.c`](https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/portable/GCC/ARM_CM4F/port.c#L293) file code sets the value of 0x400 register of NVIC to the maximum bits and expect to read back only maximum priority bits that are supported by the platform. The QEMU code doesn't unset these bits (same 0xff value written is read back):
+```
+NVIC: priority [0x400] = 0x00
+NVIC[NS]: [0x400] -> 0x00000000
+NVIC: priority [0x400] = 0xff
+NVIC[NS]: [0x400] <- 0x000000ff
+nvic_recompute_state NVIC state recomputed: vectpending 0 vectpending_prio 256 exception_prio 256
+NVIC: priority [0x400] = 0x00
+NVIC[NS]: [0x400] -> 0x000000ff
+```
+Logging function for reading and writing added in `hw/intc/armv7_nvic.c` like these:
+writing:
+```c
+    case 0x400 ... 0x5ef: /* NVIC Priority */
+        startvec = (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
+
+        for (i = 0; i < size && startvec + i < s->num_irq; i++) {
+            if (attrs.secure || s->itns[startvec + i]) {
+                qemu_log("NVIC: priority [0x%03x] = 0x%02llx\n", offset, (value >> (i * 8)) & 0xff);
+                set_prio(s, startvec + i, false, (value >> (i * 8)) & 0xff);
+            }
+        }
+        qemu_log("NVIC[%s]: [0x%03x] <- 0x%08llx\n", attrs.secure ? "S" : "NS", offset, value);
+
+        nvic_irq_update(s);
+        goto exit_ok;
+```
+reading:
+```c
+    case 0x400 ... 0x5ef: /* NVIC Priority */
+        val = 0;
+        startvec = offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */
+
+        // TODO: should return either 0x70 or 0x78
+        for (i = 0; i < size && startvec + i < s->num_irq; i++) {
+            qemu_log("NVIC: priority [0x%03x] = 0x%02x\n", offset, 8 * i);
+            if (attrs.secure || s->itns[startvec + i]) {
+                val |= s->vectors[startvec + i].prio << (8 * i);
+            }
+        }
+        qemu_log("NVIC[%s]: [0x%03x] -> 0x%08x\n", attrs.secure ? "S" : "NS", offset, val);
+        break;
+```
+Steps to reproduce:
+1. Run FreeRTOS for any ARMv7 Cortex-M platform with NVIC
+2. Observe failure to proceed to `prvPortStartFirstTask();` function.
+Additional information:
+Here is the piece of standard FreeRTOS code that runs that check:
+```c
+   /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.
+     * See https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
+    configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY );
+
+    /* This port can be used on all revisions of the Cortex-M7 core other than
+     * the r0p1 parts.  r0p1 parts should use the port from the
+     * /source/portable/GCC/ARM_CM7/r0p1 directory. */
+    configASSERT( portCPUID != portCORTEX_M7_r0p1_ID );
+    configASSERT( portCPUID != portCORTEX_M7_r0p0_ID );
+
+    #if ( configASSERT_DEFINED == 1 )
+        {
+            volatile uint32_t ulOriginalPriority;
+            volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER );
+            volatile uint8_t ucMaxPriorityValue;
+
+            /* Determine the maximum priority from which ISR safe FreeRTOS API
+             * functions can be called.  ISR safe functions are those that end in
+             * "FromISR".  FreeRTOS maintains separate thread and ISR API functions to
+             * ensure interrupt entry is as fast and simple as possible.
+             *
+             * Save the interrupt priority value that is about to be clobbered. */
+            ulOriginalPriority = *pucFirstUserPriorityRegister;
+
+            /* Determine the number of priority bits available.  First write to all
+             * possible bits. */
+            *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE;
+
+            /* Read the value back to see how many bits stuck. */
+            ucMaxPriorityValue = *pucFirstUserPriorityRegister;
+
+            /* Use the same mask on the maximum system call priority. */
+            ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue;
+
+            /* Calculate the maximum acceptable priority group value for the number
+             * of bits read back. */
+            ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS;
+
+            while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE )
+            {
+                ulMaxPRIGROUPValue--;
+                ucMaxPriorityValue <<= ( uint8_t ) 0x01;
+            }
+
+            #ifdef __NVIC_PRIO_BITS
+                {
+                    /* Check the CMSIS configuration that defines the number of
+                     * priority bits matches the number of priority bits actually queried
+                     * from the hardware. */
+                    configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
+                }
+            #endif
+
+            #ifdef configPRIO_BITS
+                {
+                    /* Check the FreeRTOS configuration that defines the number of
+                     * priority bits matches the number of priority bits actually queried
+                     * from the hardware. */
+                    configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
+                }
+            #endif
+
+            /* Shift the priority group value back to its position within the AIRCR
+             * register. */
+            ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
+            ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK;
+
+            /* Restore the clobbered interrupt priority register to its original
+             * value. */
+            *pucFirstUserPriorityRegister = ulOriginalPriority;
+        }
+    #endif /* configASSERT_DEFINED */
+```
+
+See also these pages:
+- https://www.freertos.org/RTOS-Cortex-M3-M4.html
+- https://www.freertos.org/freertos-on-qemu-mps2-an385-model.html