1 /* arch/arm/mach-msm/qdsp5/adsp_video_verify_cmd.c
3 * Verificion code for aDSP VDEC packets from userspace.
5 * Copyright (c) 2008 QUALCOMM Incorporated
6 * Copyright (C) 2008 Google, Inc.
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
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.
20 #define ADSP_DEBUG_MSGS 0
22 #define DLOG(fmt,args...) \
23 do { printk(KERN_INFO "[%s:%s:%d] "fmt, __FILE__, __func__, __LINE__, \
27 #define DLOG(x...) do {} while (0)
31 #include <mach/qdsp5/qdsp5vdeccmdi.h>
34 static inline void *high_low_short_to_ptr(unsigned short high
,
37 return (void *)((((unsigned long)high
) << 16) | ((unsigned long)low
));
40 static inline void ptr_to_high_low_short(void *ptr
, unsigned short *high
,
43 *high
= (unsigned short)((((unsigned long)ptr
) >> 16) & 0xffff);
44 *low
= (unsigned short)((unsigned long)ptr
& 0xffff);
47 static int pmem_fixup_high_low(unsigned short *high
,
49 unsigned short size_high
,
50 unsigned short size_low
,
51 struct msm_adsp_module
*module
,
52 unsigned long *addr
, unsigned long *size
)
55 unsigned long phys_size
;
58 phys_addr
= high_low_short_to_ptr(*high
, *low
);
59 phys_size
= (unsigned long)high_low_short_to_ptr(size_high
, size_low
);
60 DLOG("virt %x %x\n", phys_addr
, phys_size
);
61 if (adsp_pmem_fixup_kvaddr(module
, &phys_addr
, &kvaddr
, phys_size
)) {
62 DLOG("ah%x al%x sh%x sl%x addr %x size %x\n",
63 *high
, *low
, size_high
, size_low
, phys_addr
, phys_size
);
66 ptr_to_high_low_short(phys_addr
, high
, low
);
67 DLOG("phys %x %x\n", phys_addr
, phys_size
);
75 static int verify_vdec_pkt_cmd(struct msm_adsp_module
*module
,
76 void *cmd_data
, size_t cmd_size
)
78 unsigned short cmd_id
= ((unsigned short *)cmd_data
)[0];
79 viddec_cmd_subframe_pkt
*pkt
;
80 unsigned long subframe_pkt_addr
;
81 unsigned long subframe_pkt_size
;
82 viddec_cmd_frame_header_packet
*frame_header_pkt
;
83 int i
, num_addr
, skip
;
84 unsigned short *frame_buffer_high
, *frame_buffer_low
;
85 unsigned long frame_buffer_size
;
86 unsigned short frame_buffer_size_high
, frame_buffer_size_low
;
88 DLOG("cmd_size %d cmd_id %d cmd_data %x\n", cmd_size
, cmd_id
, cmd_data
);
89 if (cmd_id
!= VIDDEC_CMD_SUBFRAME_PKT
) {
90 printk(KERN_INFO
"adsp_video: unknown video packet %u\n",
94 if (cmd_size
< sizeof(viddec_cmd_subframe_pkt
))
97 pkt
= (viddec_cmd_subframe_pkt
*)cmd_data
;
99 if (pmem_fixup_high_low(&(pkt
->subframe_packet_high
),
100 &(pkt
->subframe_packet_low
),
101 pkt
->subframe_packet_size_high
,
102 pkt
->subframe_packet_size_low
,
108 /* deref those ptrs and check if they are a frame header packet */
109 frame_header_pkt
= (viddec_cmd_frame_header_packet
*)subframe_pkt_addr
;
111 switch (frame_header_pkt
->packet_id
) {
112 case 0xB201: /* h.264 */
115 case 0x4D01: /* mpeg-4 and h.263 */
123 frame_buffer_high
= &frame_header_pkt
->frame_buffer_0_high
;
124 frame_buffer_low
= &frame_header_pkt
->frame_buffer_0_low
;
125 frame_buffer_size
= (frame_header_pkt
->x_dimension
*
126 frame_header_pkt
->y_dimension
* 3) / 2;
127 ptr_to_high_low_short((void *)frame_buffer_size
,
128 &frame_buffer_size_high
,
129 &frame_buffer_size_low
);
130 for (i
= 0; i
< num_addr
; i
++) {
131 if (pmem_fixup_high_low(frame_buffer_high
, frame_buffer_low
,
132 frame_buffer_size_high
,
133 frame_buffer_size_low
,
137 frame_buffer_high
+= 2;
138 frame_buffer_low
+= 2;
140 /* Patch the output buffer. */
141 frame_buffer_high
+= 2*skip
;
142 frame_buffer_low
+= 2*skip
;
143 if (pmem_fixup_high_low(frame_buffer_high
, frame_buffer_low
,
144 frame_buffer_size_high
,
145 frame_buffer_size_low
, module
, NULL
, NULL
))
150 int adsp_video_verify_cmd(struct msm_adsp_module
*module
,
151 unsigned int queue_id
, void *cmd_data
,
155 case QDSP_mpuVDecPktQueue
:
157 return verify_vdec_pkt_cmd(module
, cmd_data
, cmd_size
);
159 printk(KERN_INFO
"unknown video queue %u\n", queue_id
);