]> Git Repo - qemu.git/blob - hw/omap_l4.c
omap: eliminate l4_register_io_memory
[qemu.git] / hw / omap_l4.c
1 /*
2  * TI OMAP L4 interconnect emulation.
3  *
4  * Copyright (C) 2007-2009 Nokia Corporation
5  * Written by Andrzej Zaborowski <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 or
10  * (at your option) any later version of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20 #include "hw.h"
21 #include "omap.h"
22
23 struct omap_l4_s {
24     target_phys_addr_t base;
25     int ta_num;
26     struct omap_target_agent_s ta[0];
27 };
28
29 struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
30 {
31     struct omap_l4_s *bus = g_malloc0(
32                     sizeof(*bus) + ta_num * sizeof(*bus->ta));
33
34     bus->ta_num = ta_num;
35     bus->base = base;
36
37     return bus;
38 }
39
40 target_phys_addr_t omap_l4_region_base(struct omap_target_agent_s *ta,
41                                        int region)
42 {
43     return ta->bus->base + ta->start[region].offset;
44 }
45
46 static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr)
47 {
48     struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
49
50     switch (addr) {
51     case 0x00:  /* COMPONENT */
52         return s->component;
53
54     case 0x20:  /* AGENT_CONTROL */
55         return s->control;
56
57     case 0x28:  /* AGENT_STATUS */
58         return s->status;
59     }
60
61     OMAP_BAD_REG(addr);
62     return 0;
63 }
64
65 static void omap_l4ta_write(void *opaque, target_phys_addr_t addr,
66                 uint32_t value)
67 {
68     struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
69
70     switch (addr) {
71     case 0x00:  /* COMPONENT */
72     case 0x28:  /* AGENT_STATUS */
73         OMAP_RO_REG(addr);
74         break;
75
76     case 0x20:  /* AGENT_CONTROL */
77         s->control = value & 0x01000700;
78         if (value & 1)                                  /* OCP_RESET */
79             s->status &= ~1;                            /* REQ_TIMEOUT */
80         break;
81
82     default:
83         OMAP_BAD_REG(addr);
84     }
85 }
86
87 static CPUReadMemoryFunc * const omap_l4ta_readfn[] = {
88     omap_badwidth_read16,
89     omap_l4ta_read,
90     omap_badwidth_read16,
91 };
92
93 static CPUWriteMemoryFunc * const omap_l4ta_writefn[] = {
94     omap_badwidth_write32,
95     omap_badwidth_write32,
96     omap_l4ta_write,
97 };
98
99 struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus,
100         const struct omap_l4_region_s *regions,
101         const struct omap_l4_agent_info_s *agents,
102         int cs)
103 {
104     int i, iomemtype;
105     struct omap_target_agent_s *ta = NULL;
106     const struct omap_l4_agent_info_s *info = NULL;
107
108     for (i = 0; i < bus->ta_num; i ++)
109         if (agents[i].ta == cs) {
110             ta = &bus->ta[i];
111             info = &agents[i];
112             break;
113         }
114     if (!ta) {
115         fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
116         exit(-1);
117     }
118
119     ta->bus = bus;
120     ta->start = &regions[info->region];
121     ta->regions = info->regions;
122
123     ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
124     ta->status = 0x00000000;
125     ta->control = 0x00000200;   /* XXX 01000200 for L4TAO */
126
127     iomemtype = cpu_register_io_memory(omap_l4ta_readfn,
128                     omap_l4ta_writefn, ta, DEVICE_NATIVE_ENDIAN);
129     ta->base = omap_l4_attach(ta, info->ta_region, iomemtype);
130
131     return ta;
132 }
133
134 target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
135                 int iotype)
136 {
137     target_phys_addr_t base;
138     ssize_t size;
139
140     if (region < 0 || region >= ta->regions) {
141         fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);
142         exit(-1);
143     }
144
145     base = ta->bus->base + ta->start[region].offset;
146     size = ta->start[region].size;
147     if (iotype) {
148         cpu_register_physical_memory(base, size, iotype);
149     }
150
151     return base;
152 }
This page took 0.032298 seconds and 4 git commands to generate.