source: mainline/kernel/arch/arm64/src/mach/virt/virt.c

Last change on this file was d1582b50, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Fix spacing in single-line comments using latest ccheck

This found incorrectly formatted section comments (with blocks of
asterisks or dashes). I strongly believe against using section comments
but I am not simply removing them since that would probably be
controversial.

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 2016 Petr Pavlu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup kernel_arm64_virt
30 * @{
31 */
32/** @file
33 * @brief QEMU virt platform driver.
34 */
35
36#include <arch/mach/virt/virt.h>
37#include <console/console.h>
38#include <genarch/drivers/gicv2/gicv2.h>
39#include <genarch/drivers/pl011/pl011.h>
40#include <genarch/srln/srln.h>
41#include <mm/km.h>
42#include <sysinfo/sysinfo.h>
43
44#define VIRT_VTIMER_IRQ 27
45#define VIRT_UART_IRQ 33
46#define VIRT_GIC_DISTR_ADDRESS 0x08000000
47#define VIRT_GIC_CPUI_ADDRESS 0x08010000
48#define VIRT_UART_ADDRESS 0x09000000
49
50static void virt_init(void);
51static void virt_irq_exception(unsigned int exc_no, istate_t *istate);
52static void virt_output_init(void);
53static void virt_input_init(void);
54inr_t virt_enable_vtimer_irq(void);
55size_t virt_get_irq_count(void);
56static const char *virt_get_platform_name(void);
57
58struct {
59 gicv2_t gicv2;
60 pl011_uart_t uart;
61} virt;
62
63struct arm_machine_ops virt_machine_ops = {
64 virt_init,
65 virt_irq_exception,
66 virt_output_init,
67 virt_input_init,
68 virt_enable_vtimer_irq,
69 virt_get_irq_count,
70 virt_get_platform_name
71};
72
73static void virt_init(void)
74{
75 /* Initialize interrupt controller. */
76 gicv2_distr_regs_t *distr = (void *) km_map(VIRT_GIC_DISTR_ADDRESS,
77 ALIGN_UP(sizeof(*distr), PAGE_SIZE), KM_NATURAL_ALIGNMENT,
78 PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
79 gicv2_cpui_regs_t *cpui = (void *) km_map(VIRT_GIC_CPUI_ADDRESS,
80 ALIGN_UP(sizeof(*cpui), PAGE_SIZE), KM_NATURAL_ALIGNMENT,
81 PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
82 gicv2_init(&virt.gicv2, distr, cpui);
83}
84
85static void virt_irq_exception(unsigned int exc_no, istate_t *istate)
86{
87 unsigned inum, cpuid;
88 gicv2_inum_get(&virt.gicv2, &inum, &cpuid);
89
90 /* Dispatch the interrupt. */
91 irq_t *irq = irq_dispatch_and_lock(inum);
92 if (irq) {
93 /* The IRQ handler was found. */
94 irq->handler(irq);
95 irq_spinlock_unlock(&irq->lock, false);
96 } else {
97 /* Spurious interrupt. */
98 printf("cpu%d: spurious interrupt (inum=%u)\n", CPU->id, inum);
99 }
100
101 /* Signal end of interrupt to the controller. */
102 gicv2_end(&virt.gicv2, inum, cpuid);
103}
104
105static void virt_output_init(void)
106{
107 if (!pl011_uart_init(&virt.uart, VIRT_UART_IRQ, VIRT_UART_ADDRESS))
108 return;
109
110 stdout_wire(&virt.uart.outdev);
111}
112
113static void virt_input_init(void)
114{
115 srln_instance_t *srln_instance = srln_init();
116 if (srln_instance == NULL)
117 return;
118
119 indev_t *sink = stdin_wire();
120 indev_t *srln = srln_wire(srln_instance, sink);
121 pl011_uart_input_wire(&virt.uart, srln);
122 gicv2_enable(&virt.gicv2, VIRT_UART_IRQ);
123}
124
125inr_t virt_enable_vtimer_irq(void)
126{
127 gicv2_enable(&virt.gicv2, VIRT_VTIMER_IRQ);
128 return VIRT_VTIMER_IRQ;
129}
130
131size_t virt_get_irq_count(void)
132{
133 return gicv2_inum_get_total(&virt.gicv2);
134}
135
136const char *virt_get_platform_name(void)
137{
138 return "arm64virt";
139}
140
141/** @}
142 */
Note: See TracBrowser for help on using the repository browser.