revert between 56095 -> 55830 in arch
[AROS.git] / rom / devs / ahci / ahci_aros.h
blob37bd513d71ed013cd0764a41897013b1524386a1
1 /*
2 * Copyright (C) 2012-2018, The AROS Development Team. All rights reserved.
3 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
5 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
6 */
8 #ifndef AHCI_AROS_H
9 #define AHCI_AROS_H
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <errno.h>
14 #include <assert.h>
16 #include <sys/types.h>
17 #include <sys/select.h>
19 #include <aros/debug.h>
21 #undef D2
22 #if DEBUG > 1
23 #define D2(x) x
24 #else
25 #define D2(x)
26 #endif
28 #include <proto/exec.h>
29 #include <proto/oop.h>
31 #include <hidd/pci.h>
33 #include "ahci_intern.h"
34 #include "pci_ids.h"
36 #undef kprintf
37 #define kprintf(fmt, args...) device_printf(NULL, fmt ,##args)
39 typedef uint8_t u_int8_t;
40 typedef uint16_t u_int16_t;
41 typedef uint32_t u_int32_t;
42 typedef uint64_t u_int64_t;
43 typedef unsigned int u_int;
45 #define le16toh(x) AROS_LE2WORD(x)
46 #define le32toh(x) AROS_LE2LONG(x)
47 #define htole32(x) AROS_LONG2LE(x)
48 #define htole16(x) AROS_WORD2LE(x)
50 #define PAGE_SIZE 4096
52 /* Kernel stuff */
54 #define KKASSERT(expr) ASSERT(expr)
56 int kvsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap);
57 int kvsnprintf(char *str, size_t size, const char *format, va_list ap);
58 int ksnprintf(char *buff, size_t len, const char *fmt, ...);
59 int kvcprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap);
61 static inline void bug_c(int c, void *info)
63 RawPutChar(c);
66 static inline int device_printf(device_t dev, const char *fmt, ...)
68 va_list args;
69 int err;
70 va_start(args, fmt);
71 err = kvcprintf(fmt, bug_c, NULL, 10, args);
72 va_end(args);
73 return err;
77 #define panic(fmt, args...) do { Forbid(); device_printf(NULL, fmt ,##args); Disable(); for (;;); } while (0);
79 static inline void *kmalloc(size_t size, unsigned where, unsigned flags)
81 return AllocVec(size, flags);
84 static inline void kfree(void *ptr, unsigned where)
86 FreeVec(ptr);
89 static inline void crit_enter(void)
91 Disable();
94 static inline void crit_exit(void)
96 Enable();
99 typedef struct Task *thread_t;
101 static inline int kthread_create(void (*func)(void *), void *arg, thread_t *tdp, const char *fmt, ...)
103 va_list args;
104 char name[64];
106 va_start(args, fmt);
107 kvsnprintf(name, sizeof(name), fmt, args);
108 va_end(args);
110 name[sizeof(name)-1] = 0;
112 *tdp = NewCreateTask(TASKTAG_NAME, name,
113 TASKTAG_PC, func,
114 TASKTAG_PRI, 20,
115 TASKTAG_ARG1, arg,
116 TAG_END);
118 return (*tdp == NULL) ? ENOMEM : 0;
121 /* PCI devices */
122 typedef u_int16_t pci_vendor_id_t;
123 typedef u_int16_t pci_product_id_t;
124 typedef u_int32_t pcireg_t;
126 static inline u_int32_t pci_read_config(device_t dev, int reg, int width)
128 u_int32_t val = ~0;
129 struct AHCIBase *AHCIBase = dev->dev_AHCIBase;
130 OOP_MethodID HiddPCIDeviceMethodBase = AHCIBase->ahci_HiddPCIDeviceMethodBase;
131 struct pHidd_PCIDevice_ReadConfigByte cb;
132 struct pHidd_PCIDevice_ReadConfigWord cw;
133 struct pHidd_PCIDevice_ReadConfigLong cl;
134 OOP_Object *Device = dev->dev_Object;
136 switch (width) {
137 case 1:
138 cb.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_ReadConfigByte;
139 cb.reg = reg;
140 val = (u_int32_t)OOP_DoMethod(Device, (OOP_Msg)&cb);
141 break;
143 case 2:
144 cw.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_ReadConfigWord;
145 cw.reg = reg;
146 val = (u_int32_t)OOP_DoMethod(Device, (OOP_Msg)&cw);
147 break;
149 case 4:
150 cl.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_ReadConfigLong;
151 cl.reg = reg;
152 val = (u_int32_t)OOP_DoMethod(Device, (OOP_Msg)&cl);
153 break;
156 return val;
159 static inline void pci_write_config(device_t dev, int reg, u_int32_t val, int width)
161 struct AHCIBase *AHCIBase = dev->dev_AHCIBase;
162 OOP_MethodID HiddPCIDeviceMethodBase = AHCIBase->ahci_HiddPCIDeviceMethodBase;
163 struct pHidd_PCIDevice_WriteConfigByte cb;
164 struct pHidd_PCIDevice_WriteConfigWord cw;
165 struct pHidd_PCIDevice_WriteConfigLong cl;
166 OOP_Object *Device = dev->dev_Object;
168 switch (width) {
169 case 1:
170 cb.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_WriteConfigByte;
171 cb.reg = reg;
172 cw.val = val & 0xff;
173 OOP_DoMethod(Device, (OOP_Msg)&cb);
174 break;
176 case 2:
177 cw.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_WriteConfigWord;
178 cw.reg = reg;
179 cw.val = val & 0xffff;
180 OOP_DoMethod(Device, (OOP_Msg)&cw);
181 break;
183 case 4:
184 cl.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_WriteConfigLong;
185 cl.reg = reg;
186 cl.val = val;
187 OOP_DoMethod(Device, (OOP_Msg)&cl);
188 break;
193 static inline u_int16_t pci_get_vendor(device_t dev)
195 return (u_int16_t)pci_read_config(dev, PCIR_VENDOR, 2);
198 static inline u_int16_t pci_get_device(device_t dev)
200 return (u_int16_t)pci_read_config(dev, PCIR_DEVICE, 2);
203 static inline u_int8_t pci_get_class(device_t dev)
205 return (u_int8_t)pci_read_config(dev, PCIR_CLASS, 1);
208 static inline u_int8_t pci_get_subclass(device_t dev)
210 return (u_int8_t)pci_read_config(dev, PCIR_SUBCLASS, 1);
213 /* DMA Types */
214 typedef IPTR bus_size_t;
215 typedef IPTR bus_addr_t;
216 typedef struct {
217 bus_addr_t ds_addr;
218 bus_size_t ds_len;
219 } bus_dma_segment_t;
221 struct bus_dma_tag;
222 typedef struct bus_dma_tag *bus_dma_tag_t;
224 #define BUS_DMA_MAX_SLABS 16
225 #define BUS_DMA_MAX_SEGMENTS 1024
227 typedef IPTR bus_space_tag_t;
228 typedef APTR bus_dmamap_t;
229 typedef IPTR bus_space_handle_t;
230 typedef int bus_dma_filter_t(void *arg, bus_addr_t paddr);
232 #define BUS_SPACE_MAXADDR ~0
233 #define BUS_SPACE_MAXADDR_32BIT ((ULONG)~0)
235 int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, bus_size_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat);
237 int bus_dma_tag_destroy(bus_dma_tag_t tag);
239 #define BUS_DMA_ALLOCNOW 0
240 #define BUS_DMA_ZERO MEMF_CLEAR
242 int bus_dmamem_alloc(bus_dma_tag_t tag, void **vaddr, unsigned flags, bus_dmamap_t *map);
244 bus_size_t bus_dma_tag_getmaxsize(bus_dma_tag_t tag);
246 void bus_dmamem_free(bus_dma_tag_t tag, void *vaddr, bus_dmamap_t map);
248 int bus_dmamap_create(bus_dma_tag_t tag, unsigned flags, bus_dmamap_t *map);
250 void bus_dmamap_destroy(bus_dma_tag_t tag, bus_dmamap_t map);
252 typedef void bus_dmamap_callback_t(void *info, bus_dma_segment_t *segs, int nsegs, int error);
254 #define BUS_DMA_NOWAIT 0
255 #define BUS_DMA_WAITOK 0
257 int bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, void *data, size_t len, bus_dmamap_callback_t *callback, void *info, unsigned flags);
259 #define BUS_DMASYNC_PREREAD 0
260 #define BUS_DMASYNC_PREWRITE DMA_ReadFromRAM
261 #define BUS_DMASYNC_POSTREAD (1 << 31)
262 #define BUS_DMASYNC_POSTWRITE (1 << 31) | DMA_ReadFromRAM
264 void bus_dmamap_sync(bus_dma_tag_t tag, bus_dmamap_t map, unsigned flags);
266 void bus_dmamap_unload(bus_dma_tag_t tag, bus_dmamap_t map);
268 /* Generic bus operations */
269 enum bus_resource_t {
270 SYS_RES_IRQ = 0,
271 SYS_RES_MEMORY = 1,
274 #define AHCI_IRQ_RID 0
276 struct resource {
277 bus_space_tag_t res_tag;
278 bus_space_handle_t res_handle;
279 ULONG res_size;
282 #define RF_SHAREABLE (1 << 0)
283 #define RF_ACTIVE (1 << 1)
285 struct resource *bus_alloc_resource_any(device_t dev, enum bus_resource_t type, int *rid, u_int flags);
287 int bus_release_resource(device_t dev, enum bus_resource_t type, int rid, struct resource *res);
289 static inline bus_space_tag_t rman_get_bustag(struct resource *r)
291 return r->res_tag;
294 static inline bus_space_handle_t rman_get_bushandle(struct resource *r)
296 return r->res_handle;
299 /* Bus IRQ */
300 typedef void driver_intr_t(void *arg);
302 #define INTR_MPSAFE 0
304 int bus_setup_intr(device_t dev, struct resource *r, int flags, driver_intr_t handler, void *arg, void **cookiep, void *serializer);
306 int bus_teardown_intr(device_t dev, struct resource *r, void *cookie);
308 /* Bus IO */
310 static inline int bus_space_subregion(bus_space_tag_t iot, bus_space_handle_t ioh, unsigned offset, size_t size, bus_space_handle_t *result)
312 *result = ioh + offset;
313 return 0;
316 #define BUS_SPACE_BARRIER_READ 0
317 #define BUS_SPACE_BARRIER_WRITE 0
319 static inline void bus_space_barrier(bus_space_tag_t iot, bus_space_handle_t ioh, unsigned offset, size_t size, unsigned flags)
321 /* FIXME: Sync bus area */
324 static inline u_int32_t bus_space_read_4(bus_space_tag_t iot, bus_space_handle_t ioh, unsigned offset)
326 return *(u_int32_t *)(ioh + offset);
329 static inline void bus_space_write_4(bus_space_tag_t iot, bus_space_handle_t ioh, unsigned offset, u_int32_t val)
331 *(u_int32_t *)(ioh + offset) = val;
335 /* Generic device info */
336 static inline void *device_get_softc(device_t dev)
338 return dev->dev_softc;
341 /* Lock management */
343 struct lock {
344 struct SignalSemaphore sem;
345 const char *name;
348 static inline void lockinit(struct lock *lock, const char *name, unsigned flags, unsigned count)
350 lock->name = name;
351 InitSemaphore(&lock->sem);
354 static inline void lockuninit(struct lock *lock)
356 /* Nothing needed */
359 #define LK_RELEASE (1 << 0)
360 #define LK_EXCLUSIVE (1 << 1)
361 #define LK_CANRECURSE (1 << 2)
362 #define LK_NOWAIT (1 << 3)
364 static inline int lockmgr(struct lock *lock, int flags)
366 int err = 0;
368 flags &= (LK_EXCLUSIVE | LK_NOWAIT | LK_RELEASE);
369 switch (flags) {
370 case 0:
371 ObtainSemaphoreShared(&lock->sem);
372 break;
373 case LK_EXCLUSIVE | LK_NOWAIT:
374 err = (AttemptSemaphore(&lock->sem) == FALSE) ? 1 : 0;
375 break;
376 case LK_EXCLUSIVE:
377 ObtainSemaphore(&lock->sem);
378 break;
379 case LK_RELEASE:
380 ReleaseSemaphore(&lock->sem);
381 break;
384 return err;
387 /* Events */
388 #define atomic_clear_int(ptr, val) AROS_ATOMIC_AND(*(ptr), ~(val))
389 #define atomic_set_int(ptr, val) AROS_ATOMIC_OR(*(ptr), (val))
391 /* Callouts */
393 typedef void timeout_t (void *);
395 struct callout {
396 struct Task *co_Task;
399 void callout_init_mp(struct callout *c);
401 void callout_init(struct callout *c);
403 void callout_stop(struct callout *c);
405 void callout_stop_sync(struct callout *c);
407 int callout_reset(struct callout *c, unsigned int ticks, void (*func)(void *), void *arg);
409 struct sysctl_ctx_list {};
411 /* BSD style TailQs */
412 #define TAILQ_HEAD(sname,type) struct sname { struct type *tqh_first; struct type **tqh_last; }
413 #define TAILQ_ENTRY(type) struct { struct type *tqe_next; struct type **tqe_prev; }
414 #define TAILQ_FIRST(head) ((head)->tqh_first)
415 #define TAILQ_EMPTY(head) (TAILQ_FIRST(head) == NULL)
416 #define TAILQ_INIT(head) do { \
417 (head)->tqh_first = NULL; \
418 (head)->tqh_last = &(head)->tqh_first; \
419 } while (0)
420 #define TAILQ_NEXT(elm,field) ((elm)->field.tqe_next)
421 #define TAILQ_REMOVE(head,elm,field) do { \
422 if ((elm)->field.tqe_next) \
423 (elm)->field.tqe_next->field.tqe_prev = (elm)->field.tqe_prev; \
424 else \
425 (head)->tqh_last = (elm)->field.tqe_prev; \
426 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
427 } while (0)
428 #define TAILQ_INSERT_TAIL(head,elm,field) do { \
429 (elm)->field.tqe_next = NULL; \
430 (elm)->field.tqe_prev = (head)->tqh_last; \
431 *(head)->tqh_last = (elm); \
432 (head)->tqh_last = &(elm)->field.tqe_next; \
433 } while (0)
434 #define TAILQ_FOREACH(elm,head,field) \
435 for ((elm) = ((head)->tqh_first); \
436 (elm) != NULL; (elm)=(elm)->field.tqe_next)
438 #define device_get_name(dev) "ahci.device "
439 #define device_get_unit(dev) ((dev)->dev_HostID)
441 #define M_DEVBUF 0
442 #define M_TEMP 0
443 #define M_WAITOK 0
444 #define M_INTWAIT 0
445 #define M_ZERO MEMF_CLEAR
447 static const int bootverbose = 0;
449 /* Bit operations */
450 static inline int ffs(unsigned int bits)
452 int i;
454 for (i = 0; i < 32; i++, bits >>= 1)
455 if (bits & 1)
456 return (i+1);
458 return 0;
461 struct ata_xfer;
462 void ahci_ata_io_complete(struct ata_xfer *xa);
464 #endif /* AHCI_AROS_H */