1 00:00:01,140 --> 00:00:07,680 In this lecture, we will discuss spurious interrupt and how to handle it. The spurious interrupt, as its name implies, 2 00:00:07,680 --> 00:00:14,910 is not a real interrupt. The IRQ used for spurious interrupt is the lowest priority IRQ number 3 00:00:14,910 --> 00:00:15,470 , 4 00:00:15,480 --> 00:00:22,650 that is IRQ7 for the master chip. The spurious interrupt is caused by several reasons 5 00:00:22,650 --> 00:00:23,970 and it does not always occur. 6 00:00:24,950 --> 00:00:30,790 OK, let's see how to handle it. In order to handle the spurious interrupt, we need to implement the handler 7 00:00:30,790 --> 00:00:38,030 for IRQ7. Because we don’t use the slave chip in our system, we only deal with the spurious interrupt 8 00:00:38,030 --> 00:00:43,490 in the master chip. Just like we did before, we set the idt entry first. 9 00:00:44,820 --> 00:00:50,850 Since we need three copies of the code to set idt entries, we just wrap the code into a function. 10 00:01:00,010 --> 00:01:01,950 We call it set handler. 11 00:01:07,840 --> 00:01:11,260 and we use regular return instruction to return from the function. 12 00:01:17,430 --> 00:01:23,310 Now we pass the address of idt entry to rdi register and the address of handler to rax 13 00:01:24,530 --> 00:01:27,400 and then call set handler. 14 00:01:40,830 --> 00:01:43,920 The address of the entry is the base of idt 15 00:01:44,870 --> 00:01:46,280 +32*16 16 00:01:47,260 --> 00:01:50,530 +7*16 17 00:01:51,950 --> 00:02:01,270 since the vector number for IRQ7 is 32+7 and each entry is 16 bytes. We save it in the register rdi 18 00:02:01,380 --> 00:02:02,000 . 19 00:02:05,260 --> 00:02:08,320 The handler is called SIRQ 20 00:02:09,419 --> 00:02:14,190 and copy the address in rax. Then we call set handler. 21 00:02:15,610 --> 00:02:17,290 Next we implement the handler. 22 00:02:25,050 --> 00:02:26,850 As with other interrupt handlers, 23 00:02:29,440 --> 00:02:34,390 we save the state of the cpu in the beginning and restore its state before the handler returns. 24 00:02:41,920 --> 00:02:48,610 You can define macros to wrap push and pop operations in these handlers. For simplicity, I just copy and paste the code here 25 00:02:48,610 --> 00:02:49,600 . 26 00:02:51,590 --> 00:02:56,810 In the handler, the first thing we are going to do is check to see if this is a spurious interrupt. 27 00:02:57,410 --> 00:03:04,020 To perform the check, we read the ISR register of the PIC and check the bit 7 of the value. 28 00:03:04,880 --> 00:03:11,240 If bit 7 is set, then this is a regular interrupt and we will handle it as we did with other interrupts. 29 00:03:11,870 --> 00:03:18,260 If the bit 7 is 0, this is a spurious interrupt and we simply return without sending the end of interrupt 30 00:03:18,260 --> 00:03:18,800 . 31 00:03:19,610 --> 00:03:21,860 To read the ISR register, 32 00:03:21,890 --> 00:03:23,930 we write a value to command register. 33 00:03:25,360 --> 00:03:34,450 The bit 0 to 1 specify reading IRR or ISR registers. 11 means reading ISR register. 34 00:03:34,450 --> 00:03:40,090 Bit 3 is set to 1 meaning that this is the command which reads the ISR register 35 00:03:40,090 --> 00:03:40,990 . 36 00:03:41,260 --> 00:03:42,100 So we move 37 00:03:43,720 --> 00:03:47,740 11 to al and write it to the command register of the master chip. 38 00:03:52,770 --> 00:03:56,550 Then we read the data from the command register using in instruction. 39 00:04:02,490 --> 00:04:06,600 Now the value of ISR register is in the al register. 40 00:04:08,110 --> 00:04:11,280 we test the bit 7 to see if it is 0. 41 00:04:15,870 --> 00:04:17,579 We use jz instruction, 42 00:04:20,339 --> 00:04:26,790 if bit 7 is 0, we will jump to end and return. here we use local label which starts with a dot. 43 00:04:28,510 --> 00:04:30,670 And we define the local label end. 44 00:04:36,150 --> 00:04:42,540 If the bit 7 is 1, then this is a regular interrupt. We need to send end of interrupt to the chip 45 00:04:42,540 --> 00:04:43,980 just as we did in the last video. 46 00:04:45,490 --> 00:04:51,640 So we move 20 to al and write the value to the command register. 47 00:04:53,380 --> 00:04:59,380 OK, we are done. Because the spurious interrupt does not always occur, we don't test it in this video 48 00:04:59,380 --> 00:04:59,710 .